New gcode visualization library - Added statistic of used memory

This commit is contained in:
enricoturri1966 2024-01-24 14:55:16 +01:00 committed by Lukas Matena
parent 6529f28f26
commit c20d05b15e
24 changed files with 237 additions and 30 deletions

View File

@ -26,6 +26,9 @@ extern void set_logging_level(unsigned int level);
extern unsigned get_logging_level();
// Format memory allocated, separate thousands by comma.
extern std::string format_memsize_MB(size_t n);
#if ENABLE_NEW_GCODE_VIEWER
std::string format_memsize(size_t bytes, unsigned int decimals = 1);
#endif // ENABLE_NEW_GCODE_VIEWER
// Return string to be added to the boost::log output to inform about the current process memory allocation.
// The string is non-empty if the loglevel >= info (3) or ignore_loglevel==true.
// Latter is used to get the memory info from SysInfoDialog.

View File

@ -1083,6 +1083,44 @@ std::string format_memsize_MB(size_t n)
return out + "MB";
}
#if ENABLE_NEW_GCODE_VIEWER
std::string format_memsize(size_t bytes, unsigned int decimals)
{
static constexpr const float kb = 1024.0f;
static constexpr const float mb = 1024.0f * kb;
static constexpr const float gb = 1024.0f * mb;
static constexpr const float tb = 1024.0f * gb;
const float f_bytes = static_cast<float>(bytes);
if (f_bytes < kb)
return std::to_string(bytes) + " bytes";
else if (f_bytes < mb) {
const float f_kb = f_bytes / kb;
char buf[64];
sprintf(buf, "%.*f", decimals, f_kb);
return std::to_string(bytes) + " bytes (" + std::string(buf) + "KB)";
}
else if (f_bytes < gb) {
const float f_mb = f_bytes / mb;
char buf[64];
sprintf(buf, "%.*f", decimals, f_mb);
return std::to_string(bytes) + " bytes (" + std::string(buf) + "MB)";
}
else if (f_bytes < tb) {
const float f_gb = f_bytes / gb;
char buf[64];
sprintf(buf, "%.*f", decimals, f_gb);
return std::to_string(bytes) + " bytes (" + std::string(buf) + "GB)";
}
else {
const float f_tb = f_bytes / tb;
char buf[64];
sprintf(buf, "%.*f", decimals, f_tb);
return std::to_string(bytes) + " bytes (" + std::string(buf) + "TB)";
}
}
#endif // ENABLE_NEW_GCODE_VIEWER
// Returns platform-specific string to be used as log output or parsed in SysInfoDialog.
// The latter parses the string with (semi)colons as separators, it should look about as
// "desc1: value1; desc2: value2" or similar (spaces should not matter).

View File

@ -14,7 +14,6 @@ struct ColorPrint
uint8_t extruder_id{ 0 };
uint8_t color_id{ 0 };
uint32_t layer_id{ 0 };
// float layer_z{ 0.0f };
std::array<float, TIME_MODES_COUNT> times{ 0.0f, 0.0f };
};

View File

@ -25,19 +25,6 @@ static const Palette DEFAULT_RANGES_COLORS{ {
{ 148, 38, 22 } // reddish
} };
//
// Helper class to interpolate between colors defined in a palette.
// Interpolation can be done linearly or logarithmically.
// Usage:
// 1) Define an instance of ColorRange of the desired interpolation type
// ColorRange range(EColorRangeType::Linear);
// 2) Pass to the instance all the values needed to setup the range:
// for (size_t i = 0; i < my_data.size(); ++i) {
// range.update(my_data[i]);
// }
// 3) Get the color at the desired value:
// Color c = range.get_color_at(value);
//
class ColorRange
{
public:
@ -79,6 +66,10 @@ public:
// get_palette().size() - If more than two distinct values were detected while setting up this ColorRange.
//
std::vector<float> get_values() const;
//
// Return the size of the palette, in bytes
//
size_t size_in_bytes_cpu() const;
static const ColorRange DUMMY_COLOR_RANGE;

View File

@ -100,9 +100,9 @@ struct PathVertex
// Return true if the segment was generated by custom gcode
//
bool is_custom_gcode() const;
};
static const PathVertex DUMMY_PATH_VERTEX = PathVertex();
static const PathVertex DUMMY_PATH_VERTEX;
};
} // namespace libvgcode

View File

@ -351,6 +351,14 @@ public:
// Return the axes aligned bounding box of the toolpaths.
//
AABox get_bounding_box(EBBoxType type) const;
//
// Return the size of the used cpu memory, in bytes
//
size_t get_used_cpu_memory() const;
//
// Return the size of the used gpu memory, in bytes
//
size_t get_used_gpu_memory() const;
#if VGCODE_ENABLE_DEBUG_CODE
size_t get_enabled_segments_count() const;

View File

@ -84,13 +84,16 @@ struct BitSet
return oldval xor (oldval and mask);
}
std::pair<size_t, size_t> get_coords(size_t index) const
{
std::pair<size_t, size_t> get_coords(size_t index) const {
const size_t block_idx = index / (sizeof(T) * 8);
const size_t bit_idx = index % (sizeof(T) * 8);
return { block_idx, bit_idx };
}
size_t size_in_bytes_cpu() const {
return blocks.size() * sizeof(T);
}
size_t size{ 0 };
std::vector<T> blocks{ 0 };
};

View File

@ -85,6 +85,9 @@ void CogMarker::init(uint8_t resolution, float radius)
}
}
m_size_in_bytes_gpu += vertices.size() * sizeof(float);
m_size_in_bytes_gpu += indices.size() * sizeof(uint16_t);
const size_t vertex_stride = 6 * sizeof(float);
const size_t position_offset = 0;
const size_t normal_offset = 3 * sizeof(float);
@ -126,6 +129,8 @@ void CogMarker::shutdown()
glsafe(glDeleteVertexArrays(1, &m_vao_id));
m_vao_id = 0;
}
m_size_in_bytes_gpu = 0;
}
void CogMarker::render()

View File

@ -22,29 +22,33 @@ public:
CogMarker& operator = (CogMarker&& other) = delete;
//
// Initialize gpu buffers.
// Initialize gpu buffers
//
void init(uint8_t resolution, float radius);
//
// Release gpu buffers.
// Release gpu buffers
//
void shutdown();
//
// Render the marker
//
void render();
//
// Update values used to calculate the center of gravity
//
void update(const Vec3& position, float mass);
//
// Reset values used to calculate the center of gravity
//
void reset();
//
// Return the calculated center of gravity
// Return the calculated center of gravity position
//
Vec3 get_position() const;
//
// Return the size of the data sent to gpu, in bytes.
//
size_t size_in_bytes_gpu() const { return m_size_in_bytes_gpu; }
private:
//
@ -52,7 +56,9 @@ private:
//
float m_total_mass{ 0.0f };
Vec3 m_total_position{ 0.0f, 0.0f, 0.0f };
//
// The count of indices stored into the ibo buffer.
//
uint16_t m_indices_count{ 0 };
//
// gpu buffers ids.
@ -60,6 +66,10 @@ private:
unsigned int m_vao_id{ 0 };
unsigned int m_vbo_id{ 0 };
unsigned int m_ibo_id{ 0 };
//
// Size of the data sent to gpu, in bytes.
//
size_t m_size_in_bytes_gpu{ 0 };
};
} // namespace libvgcode

View File

@ -4,6 +4,8 @@
///|/
#include "../include/ColorRange.hpp"
#include "Utils.hpp"
#include <algorithm>
#include <assert.h>
#include <cmath>
@ -112,6 +114,12 @@ std::vector<float> ColorRange::get_values() const
return ret;
}
size_t ColorRange::size_in_bytes_cpu() const
{
size_t ret = STDVEC_MEMSIZE(m_palette, Color);
return ret;
}
void ColorRange::update(float value)
{
if (value != m_range[0] && value != m_range[1])

View File

@ -5,6 +5,7 @@
#include "Layers.hpp"
#include "../include/PathVertex.hpp"
#include "Utils.hpp"
#include <assert.h>
#include <algorithm>
@ -73,4 +74,10 @@ size_t Layers::get_layer_id_at(float z) const
return std::distance(m_items.begin(), iter);
}
size_t Layers::size_in_bytes_cpu() const
{
size_t ret = STDVEC_MEMSIZE(m_items, Item);
return ret;
}
} // namespace libvgcode

View File

@ -40,6 +40,8 @@ public:
return (layer_id < m_items.size()) ? m_items[layer_id].contains_colorprint_options : false;
}
size_t size_in_bytes_cpu() const;
private:
struct Item
{

View File

@ -50,6 +50,9 @@ void OptionTemplate::init(uint8_t resolution)
add_vertex(pos, norm, bottom_vertices);
}
m_size_in_bytes_gpu += top_vertices.size() * sizeof(float);
m_size_in_bytes_gpu += bottom_vertices.size() * sizeof(float);
const size_t vertex_stride = 6 * sizeof(float);
const size_t position_offset = 0;
const size_t normal_offset = 3 * sizeof(float);
@ -101,6 +104,8 @@ void OptionTemplate::shutdown()
glsafe(glDeleteVertexArrays(1, &m_top_vao_id));
m_top_vao_id = 0;
}
m_size_in_bytes_gpu = 0;
}
void OptionTemplate::render(size_t count)

View File

@ -30,6 +30,11 @@ public:
void shutdown();
void render(size_t count);
//
// Return the size of the data sent to gpu, in bytes.
//
size_t size_in_bytes_gpu() const { return m_size_in_bytes_gpu; }
private:
uint8_t m_resolution{ 0 };
uint8_t m_vertices_count{ 0 };
@ -40,6 +45,10 @@ private:
unsigned int m_top_vbo_id{ 0 };
unsigned int m_bottom_vao_id{ 0 };
unsigned int m_bottom_vbo_id{ 0 };
//
// Size of the data sent to gpu, in bytes.
//
size_t m_size_in_bytes_gpu{ 0 };
};
} // namespace libvgcode

View File

@ -6,6 +6,8 @@
namespace libvgcode {
const PathVertex PathVertex::DUMMY_PATH_VERTEX = PathVertex();
bool PathVertex::is_extrusion() const
{
return type == EMoveType::Extrude;

View File

@ -31,6 +31,8 @@ void SegmentTemplate::init()
if (m_vao_id != 0)
return;
m_size_in_bytes_gpu += VERTEX_DATA.size() * sizeof(uint8_t);
int curr_vertex_array;
glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array));
int curr_array_buffer;
@ -59,6 +61,8 @@ void SegmentTemplate::shutdown()
glsafe(glDeleteVertexArrays(1, &m_vao_id));
m_vao_id = 0;
}
m_size_in_bytes_gpu = 0;
}
void SegmentTemplate::render(size_t count)

View File

@ -29,12 +29,21 @@ public:
void shutdown();
void render(size_t count);
//
// Return the size of the data sent to gpu, in bytes.
//
size_t size_in_bytes_gpu() const { return m_size_in_bytes_gpu; }
private:
//
// gpu buffers ids.
//
unsigned int m_vao_id{ 0 };
unsigned int m_vbo_id{ 0 };
//
// Size of the data sent to gpu, in bytes.
//
size_t m_size_in_bytes_gpu{ 0 };
};
} // namespace libvgcode

View File

@ -105,6 +105,9 @@ void ToolMarker::init(uint16_t resolution, float tip_radius, float tip_height, f
add_triangle(5 * resolution + 1, v3, i + 5 * resolution + 2, indices);
}
m_size_in_bytes_gpu += vertices.size() * sizeof(float);
m_size_in_bytes_gpu += indices.size() * sizeof(uint16_t);
const size_t vertex_stride = 6 * sizeof(float);
const size_t position_offset = 0;
const size_t normal_offset = 3 * sizeof(float);
@ -146,6 +149,8 @@ void ToolMarker::shutdown()
glsafe(glDeleteVertexArrays(1, &m_vao_id));
m_vao_id = 0;
}
m_size_in_bytes_gpu = 0;
}
void ToolMarker::render()

View File

@ -47,6 +47,11 @@ public:
float get_alpha() const { return m_alpha; }
void set_alpha(float alpha) { m_alpha = std::clamp(alpha, 0.25f, 0.75f); }
//
// Return the size of the data sent to gpu, in bytes.
//
size_t size_in_bytes_gpu() const { return m_size_in_bytes_gpu; }
private:
bool m_enabled{ false };
Vec3 m_position{ 0.0f, 0.0f, 0.0f };
@ -61,6 +66,10 @@ private:
unsigned int m_vao_id{ 0 };
unsigned int m_vbo_id{ 0 };
unsigned int m_ibo_id{ 0 };
//
// Size of the data sent to gpu, in bytes.
//
size_t m_size_in_bytes_gpu{ 0 };
};
} // namespace libvgcode

View File

@ -7,6 +7,12 @@
#include "../include/Types.hpp"
#ifdef _WIN32
#define STDVEC_MEMSIZE(NAME, TYPE) NAME.capacity() * ((sizeof(TYPE) + __alignof(TYPE) - 1) / __alignof(TYPE)) * __alignof(TYPE)
#else
#define STDVEC_MEMSIZE(NAME, TYPE) NAME.capacity() * ((sizeof(TYPE) + alignof(TYPE) - 1) / alignof(TYPE)) * alignof(TYPE)
#endif // _WIN32
namespace libvgcode {
extern void add_vertex(const Vec3& position, const Vec3& normal, std::vector<float>& vertices);

View File

@ -337,6 +337,16 @@ AABox Viewer::get_bounding_box(EBBoxType type) const
return m_impl->get_bounding_box(type);
}
size_t Viewer::get_used_cpu_memory() const
{
return m_impl->get_used_cpu_memory();
}
size_t Viewer::get_used_gpu_memory() const
{
return m_impl->get_used_gpu_memory();
}
#if VGCODE_ENABLE_DEBUG_CODE
size_t Viewer::get_enabled_segments_count() const
{

View File

@ -577,6 +577,9 @@ void ViewerImpl::load(GCodeInputData&& gcode_data)
heights_widths_angles.push_back({ v.height, v.width, angle });
}
m_positions_tex_size = positions.size() * sizeof(Vec3);
m_height_width_angle_tex_size = heights_widths_angles.size() * sizeof(Vec3);
if (!positions.empty()) {
int old_bound_texture = 0;
glsafe(glGetIntegerv(GL_TEXTURE_BINDING_BUFFER, &old_bound_texture));
@ -693,6 +696,9 @@ void ViewerImpl::update_enabled_entities()
else
m_enabled_options_range.reset();
m_enabled_segments_tex_size = enabled_segments.size() * sizeof(uint32_t);
m_enabled_options_tex_size = enabled_options.size() * sizeof(uint32_t);
// update gpu buffer for enabled segments
assert(m_enabled_segments_buf_id > 0);
glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_enabled_segments_buf_id));
@ -749,6 +755,8 @@ void ViewerImpl::update_colors()
encode_color(DUMMY_COLOR) : encode_color(get_vertex_color(m_vertices[i]));
}
m_colors_tex_size = colors.size() * sizeof(float);
// update gpu buffer for colors
assert(m_colors_buf_id > 0);
glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_colors_buf_id));
@ -1091,6 +1099,47 @@ void ViewerImpl::set_wipes_radius(float radius)
update_heights_widths();
}
size_t ViewerImpl::get_used_cpu_memory() const
{
size_t ret = sizeof(*this);
ret += m_layers.size_in_bytes_cpu();
ret += STDVEC_MEMSIZE(m_options, EOptionType);
ret += m_used_extruders.size() * sizeof(std::map<uint8_t, ColorPrint>::value_type);
ret += m_extrusion_roles_colors.size() * sizeof(std::map<EGCodeExtrusionRole, Color>::value_type);
ret += m_options_colors.size() * sizeof(std::map<EOptionType, Color>::value_type);
ret += STDVEC_MEMSIZE(m_vertices, PathVertex);
ret += m_valid_lines_bitset.size_in_bytes_cpu();
ret += m_height_range.size_in_bytes_cpu();
ret += m_width_range.size_in_bytes_cpu();
ret += m_speed_range.size_in_bytes_cpu();
ret += m_fan_speed_range.size_in_bytes_cpu();
ret += m_temperature_range.size_in_bytes_cpu();
ret += m_volumetric_rate_range.size_in_bytes_cpu();
for (size_t i = 0; i < COLOR_RANGE_TYPES_COUNT; ++i) {
ret += m_layer_time_range[i].size_in_bytes_cpu();
}
ret += STDVEC_MEMSIZE(m_tool_colors, Color);
ret += STDVEC_MEMSIZE(m_color_print_colors, Color);
return ret;
}
size_t ViewerImpl::get_used_gpu_memory() const
{
size_t ret = 0;
ret += m_segment_template.size_in_bytes_gpu();
ret += m_option_template.size_in_bytes_gpu();
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
ret += m_tool_marker.size_in_bytes_gpu();
ret += m_cog_marker.size_in_bytes_gpu();
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
ret += m_positions_tex_size;
ret += m_height_width_angle_tex_size;
ret += m_colors_tex_size;
ret += m_enabled_segments_tex_size;
ret += m_enabled_options_tex_size;
return ret;
}
static bool is_visible(const PathVertex& v, const Settings& settings)
{
const EOptionType option_type = move_type_to_option(v.type);

View File

@ -116,7 +116,7 @@ public:
const PathVertex& get_current_vertex() const { return get_vertex_at(get_current_vertex_id()); }
size_t get_current_vertex_id() const { return static_cast<size_t>(m_view_range.get_visible()[1]); }
const PathVertex& get_vertex_at(size_t id) const {
return (id < m_vertices.size()) ? m_vertices[id] : DUMMY_PATH_VERTEX;
return (id < m_vertices.size()) ? m_vertices[id] : PathVertex::DUMMY_PATH_VERTEX;
}
float get_estimated_time_at(size_t id) const;
Color get_vertex_color(const PathVertex& vertex) const;
@ -163,6 +163,9 @@ public:
float get_wipes_radius() const { return m_wipes_radius; }
void set_wipes_radius(float radius);
size_t get_used_cpu_memory() const;
size_t get_used_gpu_memory() const;
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
Vec3 get_cog_marker_position() const { return m_cog_marker.get_position(); }
@ -293,7 +296,7 @@ private:
unsigned int m_tool_marker_shader_id{ 0 };
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
//
// Cache for OpenGL uniforms id for segments shader
// Caches for OpenGL uniforms id for segments shader
//
int m_uni_segments_view_matrix_id{ -1 };
int m_uni_segments_projection_matrix_id{ -1 };
@ -303,7 +306,7 @@ private:
int m_uni_segments_colors_tex_id{ -1 };
int m_uni_segments_segment_index_tex_id{ -1 };
//
// Cache for OpenGL uniforms id for options shader
// Caches for OpenGL uniforms id for options shader
//
int m_uni_options_view_matrix_id{ -1 };
int m_uni_options_projection_matrix_id{ -1 };
@ -313,14 +316,14 @@ private:
int m_uni_options_segment_index_tex_id{ -1 };
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
//
// Cache for OpenGL uniforms id for cog marker shader
// Caches for OpenGL uniforms id for cog marker shader
//
int m_uni_cog_marker_world_center_position{ -1 };
int m_uni_cog_marker_scale_factor{ -1 };
int m_uni_cog_marker_view_matrix{ -1 };
int m_uni_cog_marker_projection_matrix{ -1 };
//
// Cache for OpenGL uniforms id for tool marker shader
// Caches for OpenGL uniforms id for tool marker shader
//
int m_uni_tool_marker_world_origin{ -1 };
int m_uni_tool_marker_scale_factor{ -1 };
@ -353,6 +356,14 @@ private:
//
unsigned int m_enabled_options_buf_id{ 0 };
unsigned int m_enabled_options_tex_id{ 0 };
//
// Caches for size of data sent to gpu, in bytes
//
size_t m_positions_tex_size{ 0 };
size_t m_height_width_angle_tex_size{ 0 };
size_t m_colors_tex_size{ 0 };
size_t m_enabled_segments_tex_size{ 0 };
size_t m_enabled_options_tex_size{ 0 };
void update_view_full_range();
void update_color_ranges();

View File

@ -3882,6 +3882,20 @@ void GCodeViewer::render_toolpaths()
ImGui::Separator();
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, "cpu memory");
ImGui::TableSetColumnIndex(1);
imgui.text(format_memsize(m_viewer.get_used_cpu_memory()));
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, "gpu memory");
ImGui::TableSetColumnIndex(1);
imgui.text(format_memsize(m_viewer.get_used_gpu_memory()));
ImGui::Separator();
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, "layers range");