1#include "performance_monitor.h"
3#include <cgv/gui/theme_info.h>
4#include <cgv/math/ftransform.h>
5#include <cgv_g2d/msdf_gl_font_renderer.h>
10performance_monitor::performance_monitor() {
15 layout.padding = padding();
16 layout.total_size =
ivec2(180, 80);
20 bar_renderer = cgv::g2d::generic_2d_renderer(cgv::g2d::shaders::rectangle);
25 cgv::g2d::ref_msdf_gl_font_renderer_2d(ctx, -1);
29 bar_renderer.destruct(ctx);
31 static_text_geometry.destruct(ctx);
32 dynamic_text_geometry.destruct(ctx);
38 layout.total_size.
y() = show_plot ? 80 : 45;
55 cgv::g2d::ref_msdf_gl_font_renderer_2d(ctx, 1);
57 register_shader(
"rectangle", cgv::g2d::shaders::rectangle);
58 register_shader(
"line", cgv::g2d::shaders::line);
62 success &= bar_renderer.init(ctx);
63 success &= static_text_geometry.init(ctx);
64 success &= dynamic_text_geometry.init(ctx);
67 { 0.0f,
rgb(0.5f, 1.0f, 0.5f) },
68 { 0.25f,
rgb(0.0f, 0.9f, 0.0f) },
69 { 0.5f,
rgb(0.8f, 0.9f, 0.0f) },
70 { 1.0f,
rgb(0.9f, 0.0f, 0.0f) }
78 if(ensure_layout(ctx)) {
80 create_static_texts(ctx);
81 create_dynamic_texts(ctx);
91 update_dynamic_texts(ctx);
98 auto& font_renderer = cgv::g2d::ref_msdf_gl_font_renderer_2d(ctx);
102 content_canvas.enable_shader(ctx,
"rectangle");
103 content_canvas.set_style(ctx, border_style);
104 content_canvas.draw_shape(ctx, layout.plot_rect.position - 1, layout.plot_rect.size + 2);
107 bar_renderer.render(ctx, content_canvas, cgv::render::PT_POINTS, bars, bar_style);
110 const auto& r = layout.plot_rect;
111 ivec2 a(r.x() + 12, r.center().y());
115 content_canvas.enable_shader(ctx,
"line");
116 content_canvas.set_style(ctx, line_style);
117 content_canvas.draw_shape2(ctx, a, b);
118 content_canvas.disable_current_shader(ctx);
122 font_renderer.render(ctx, content_canvas, static_text_geometry, text_style);
123 font_renderer.render(ctx, content_canvas, dynamic_text_geometry, text_style);
138 ++
monitor.interval_frame_count;
140 double seconds_since_start =
monitor.timer.get_elapsed_time();
141 monitor.delta_time = seconds_since_start -
monitor.last_seconds_since_start;
145 monitor.last_seconds_since_start = seconds_since_start;
150 monitor.interval_frame_count = 0u;
155void performance_monitor::set_invert_color(
bool flag) {
161void performance_monitor::enable_monitoring(
bool enabled) {
166void performance_monitor::enable_monitoring_only_when_visible(
bool enabled) {
182 add_member_control(
this,
"Measure Interval (s)",
monitor.interval,
"value_slider",
"min=0.01;max=1;step=0.01;ticks=true");
188void performance_monitor::init_styles() {
189 auto& theme = cgv::gui::theme_info::instance();
190 rgb border_color = theme.text();
193 border_color = pow(
rgb(1.0f) - pow(border_color, 2.2f), 1.0f / 2.2f);
197 border_style.border_color =
rgba(border_color, 1.0);
198 border_style.border_width = 1.0f;
199 border_style.feather_width = 0.0f;
200 border_style.use_blending =
true;
202 line_style.use_blending =
true;
203 line_style.fill_color =
rgba(border_color, invert_color ? 0.666f : 0.333f);
204 line_style.feather_width = 0.0f;
205 line_style.dash_length = 10.0f;
207 bar_style.use_fill_color =
false;
208 bar_style.feather_width = 0.0f;
211 text_style.fill_color = border_color;
212 text_style.font_size = 12.0f;
214 tick_text_style = text_style;
215 tick_text_style.font_size = 10.0f;
220 static_text_geometry.clear();
222 std::vector<std::string> texts = {
223 "Frames per second:",
227 const float line_spacing = 1.25f * text_style.font_size;
228 cgv::g2d::rect content_rect =
static_cast<cgv::g2d::rect
>(layout.content_rect);
230 vec3 caret_pos(content_rect.x(), content_rect.y1() - text_style.font_size, 0.0f);
231 static_text_geometry.positions.push_back(caret_pos);
232 caret_pos.y() -= line_spacing;
233 static_text_geometry.positions.push_back(caret_pos);
235 static_text_geometry.alignments = {
242 texts.push_back(
"30");
243 texts.push_back(
"60");
244 texts.push_back(
"120");
246 cgv::g2d::rect plot_rect =
static_cast<cgv::g2d::rect
>(layout.plot_rect);
248 caret_pos =
vec3(plot_rect.x(), plot_rect.y1(), 0.0f);
249 static_text_geometry.positions.push_back(caret_pos);
250 caret_pos.y() = plot_rect.center().y();
251 static_text_geometry.positions.push_back(caret_pos);
252 caret_pos.y() = plot_rect.y();
253 static_text_geometry.positions.push_back(caret_pos);
260 static_text_geometry.texts = texts;
261 static_text_geometry.create(ctx);
266 dynamic_text_geometry.clear();
268 dynamic_text_geometry.texts = {
"",
"" };
269 dynamic_text_geometry.create(ctx);
271 const float line_spacing = 1.25f * text_style.font_size;
272 cgv::g2d::rect content_rect =
static_cast<cgv::g2d::rect
>(layout.content_rect);
274 vec3 caret_pos =
vec3(content_rect.x1(), content_rect.y1() - text_style.font_size, 0.0f);
275 dynamic_text_geometry.positions.push_back(caret_pos);
276 caret_pos.y() -= line_spacing;
277 dynamic_text_geometry.positions.push_back(caret_pos);
279 dynamic_text_geometry.alignments = {
287 std::vector<std::string> value_labels(2);
289 std::stringstream ss;
294 value_labels[0] = ss.str();
296 ss.str(std::string());
300 ss << 1000.0 /
monitor.avg_fps;
302 value_labels[1] = ss.str();
304 dynamic_text_geometry.texts = value_labels;
305 dynamic_text_geometry.create(ctx);
309void performance_monitor::update_plot() {
311 ivec2 plot_size = layout.plot_rect.size;
313 float a =
static_cast<float>(1000.0 *
monitor.delta_time / 33.333333333);
314 float b = std::min(a, 1.0f);
315 float bar_height = plot_size.y() * b;
316 bar_height = std::max(bar_height, 1.0f);
318 rgb bar_color = a > 1.0f ?
rgb(0.7f, 0.0f, 0.0f) : color_map.interpolate(b);
320 if(bars.render_count() < plot_size.x()) {
321 for(
auto& position : bars.position)
322 position.x() -= 1.0f;
324 int x = layout.plot_rect.x1() - 1;
326 float bar_x =
static_cast<float>(x);
327 bars.add(
vec2(bar_x,
static_cast<float>(layout.plot_rect.y())),
vec2(1.0f, bar_height), bar_color);
330 for(
size_t i = 0; i < bars.position.size() - 1; ++i) {
331 bars.size[i].y() = bars.size[i + 1].y();
332 bars.color[i] = bars.color[i + 1];
335 bars.size.back() =
vec2(1.0f, bar_height);
336 bars.color.back() = bar_color;
339 bars.set_out_of_date();
void set_name(const std::string &_name)
set a new parent node
data::ref_ptr< control< T > > add_member_control(cgv::base::base *base_ptr, const std::string &label, T &value, const std::string &gui_type="", const std::string &options="", const std::string &align="\n")
add control with callback to cgv::base::on_set method on cgv::gui::control::value_change
T & y()
return second component
T & x()
return first component
bool init(cgv::render::context &ctx) override
this method is called after creation or recreation of the context, return whether all necessary funct...
virtual void on_set(void *member_ptr) override
default implementation of that calls handle_member_change and afterwards upates the member in the gui...
void clear(cgv::render::context &ctx) override
clear all objects living in the context like textures or display lists
void set_size(const ivec2 &size)
set the default size of the overlay before stretch gets applied
cgv::g2d::irect get_rectangle() const
return the current rectangle area (in screen coordinates) of the overlay taking layout into account
gui_options_t gui_options
options for the GUI creation of this overlay (must be set before GUI creation)
bool background_visible_
whether the background is visible (true by default)
base class for all drawables, which is independent of the used rendering API.
context * get_context() const
access the current context. The context will be available latestly in the init method but not in the ...
virtual void after_finish(context &)
this method is called in one pass over all drawables after finish frame
bool is_visible() const
check whether the drawable is visible
@ TA_BOTTOM_RIGHT
bottom right corner of text bounds
@ TA_BOTTOM_LEFT
bottom left corner of text bounds
@ TA_TOP_LEFT
top left corner of text bounds
@ TA_LEFT
center of left edge of text bounds
this header is dependency free
cgv::media::color< float, cgv::media::RGB, cgv::media::OPACITY > rgba
declare rgba color type with 32 bit components
cgv::media::color< float, cgv::media::RGB > rgb
declare rgb color type with 32 bit components
cgv::math::fvec< int32_t, 2 > ivec2
declare type of 2d 32 bit integer vectors
cgv::math::fvec< float, 2 > vec2
declare type of 2d single precision floating point vectors
cgv::math::fvec< float, 3 > vec3
declare type of 3d single precision floating point vectors
bool allow_stretch
whether to show the stretch options (show_layout_options must be enabled)