From 9aee934d530af9633e04dd842fd778b119039fbb Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Tue, 23 Aug 2022 11:28:25 +0200 Subject: [PATCH] Speed improvement of initial G-code preview: 1) Preallocating the vertex / index buffers to limit reallocation. 2) Inlining the pushing into the vertex / index buffers. 3) Running the vertex buffer generator on a limited number of threads as the generator does not scale well due to memory pressure. Not using all the threads leaves some of the threads to G-code generator. --- src/slic3r/GUI/3DScene.cpp | 7 +++++++ src/slic3r/GUI/GLCanvas3D.cpp | 6 ++++++ src/slic3r/GUI/GLModel.cpp | 25 ++----------------------- src/slic3r/GUI/GLModel.hpp | 15 +++++++++++++-- 4 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index f25b89da8..76ae5e755 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -1429,6 +1429,13 @@ static void thick_lines_to_geometry( double width_initial = 0.0; double bottom_z_initial = 0.0; + // Reserve for a smooth path. Likley the path will not be that smooth, but better than nothing. + // Allocated 1.5x more data than minimum. + // Number of indices, not triangles. + geometry.reserve_more_indices((lines.size() * 8 * 3) * 3 / 2); + // Number of vertices, not floats. + geometry.reserve_more_vertices(((lines.size() + 1) * 4) * 3 / 2); + // loop once more in case of closed loops const size_t lines_end = closed ? (lines.size() + 1) : lines.size(); for (size_t ii = 0; ii < lines_end; ++ii) { diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index a5291481d..cc9e1307c 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -6873,6 +6873,11 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c return volume; }; const size_t volumes_cnt_initial = m_volumes.volumes.size(); + // Limit the number of threads as the code below does not scale well due to memory pressure. + // (most of the time is spent in malloc / free / memmove) + // Not using all the threads leaves some of the threads to G-code generator. + tbb::task_arena limited_arena(std::min(tbb::this_task_arena::max_concurrency(), 4)); + limited_arena.execute([&ctxt, grain_size, &new_volume, is_selected_separate_extruder, this]{ tbb::parallel_for( tbb::blocked_range(0, ctxt.layers.size(), grain_size), [&ctxt, &new_volume, is_selected_separate_extruder, this](const tbb::blocked_range& range) { @@ -7047,6 +7052,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c vol->indexed_vertex_array.shrink_to_fit(); #endif // ENABLE_LEGACY_OPENGL_REMOVAL }); + }); // task arena BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - finalizing results" << m_volumes.log_memory_info() << log_memory_info(); // Remove empty volumes from the newly added volumes. diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index e6bdae415..6714630e5 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -94,22 +94,8 @@ void GLModel::Geometry::add_vertex(const Vec3f& position) void GLModel::Geometry::add_vertex(const Vec3f& position, const Vec2f& tex_coord) { assert(format.vertex_layout == EVertexLayout::P3T2); - vertices.emplace_back(position.x()); - vertices.emplace_back(position.y()); - vertices.emplace_back(position.z()); - vertices.emplace_back(tex_coord.x()); - vertices.emplace_back(tex_coord.y()); -} - -void GLModel::Geometry::add_vertex(const Vec3f& position, const Vec3f& normal) -{ - assert(format.vertex_layout == EVertexLayout::P3N3); - vertices.emplace_back(position.x()); - vertices.emplace_back(position.y()); - vertices.emplace_back(position.z()); - vertices.emplace_back(normal.x()); - vertices.emplace_back(normal.y()); - vertices.emplace_back(normal.z()); + vertices.insert(vertices.end(), position.data(), position.data() + 3); + vertices.insert(vertices.end(), tex_coord.data(), tex_coord.data() + 2); } void GLModel::Geometry::add_index(unsigned int id) @@ -123,13 +109,6 @@ void GLModel::Geometry::add_line(unsigned int id1, unsigned int id2) indices.emplace_back(id2); } -void GLModel::Geometry::add_triangle(unsigned int id1, unsigned int id2, unsigned int id3) -{ - indices.emplace_back(id1); - indices.emplace_back(id2); - indices.emplace_back(id3); -} - Vec2f GLModel::Geometry::extract_position_2(size_t id) const { const size_t p_stride = position_stride_floats(format); diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index 3176780bf..71745acd9 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -4,6 +4,7 @@ #include "libslic3r/Point.hpp" #include "libslic3r/BoundingBox.hpp" #include "libslic3r/Color.hpp" +#include "libslic3r/Utils.hpp" #include #include @@ -85,13 +86,19 @@ namespace GUI { ColorRGBA color{ ColorRGBA::BLACK() }; void reserve_vertices(size_t vertices_count) { vertices.reserve(vertices_count * vertex_stride_floats(format)); } + void reserve_more_vertices(size_t vertices_count) { vertices.reserve(next_highest_power_of_2(vertices.size() + vertices_count * vertex_stride_floats(format))); } void reserve_indices(size_t indices_count) { indices.reserve(indices_count); } + void reserve_more_indices(size_t indices_count) { indices.reserve(next_highest_power_of_2(indices.size() + indices_count)); } void add_vertex(const Vec2f& position); // EVertexLayout::P2 void add_vertex(const Vec2f& position, const Vec2f& tex_coord); // EVertexLayout::P2T2 void add_vertex(const Vec3f& position); // EVertexLayout::P3 void add_vertex(const Vec3f& position, const Vec2f& tex_coord); // EVertexLayout::P3T2 - void add_vertex(const Vec3f& position, const Vec3f& normal); // EVertexLayout::P3N3 + void add_vertex(const Vec3f& position, const Vec3f& normal) { // EVertexLayout::P3N3 + assert(format.vertex_layout == EVertexLayout::P3N3); + vertices.insert(vertices.end(), position.data(), position.data() + 3); + vertices.insert(vertices.end(), normal.data(), normal.data() + 3); + } void set_vertex(size_t id, const Vec3f& position, const Vec3f& normal); // EVertexLayout::P3N3 @@ -99,7 +106,11 @@ namespace GUI { void add_index(unsigned int id); void add_line(unsigned int id1, unsigned int id2); - void add_triangle(unsigned int id1, unsigned int id2, unsigned int id3); + void add_triangle(unsigned int id1, unsigned int id2, unsigned int id3){ + indices.emplace_back(id1); + indices.emplace_back(id2); + indices.emplace_back(id3); + } Vec2f extract_position_2(size_t id) const; Vec3f extract_position_3(size_t id) const;