diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 14e2a8bde..9b9067af3 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -10,6 +10,8 @@ #define ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM (1 && ENABLE_1_42_0) // Add double click on gizmo grabbers to reset transformation components to their default value #define ENABLE_GIZMOS_RESET (1 && ENABLE_1_42_0) +// Uses a unique opengl context +#define ENABLE_USE_UNIQUE_GLCONTEXT (1 && ENABLE_1_42_0) #endif // _technologies_h_ diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 2414e8c9b..d78fb9c1f 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1956,7 +1956,6 @@ wxDEFINE_EVENT(EVT_GIZMO_SCALE, Vec3dEvent); wxDEFINE_EVENT(EVT_GIZMO_ROTATE, Vec3dEvent); wxDEFINE_EVENT(EVT_GIZMO_FLATTEN, Vec3dEvent); - GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas) : m_canvas(canvas) , m_context(nullptr) @@ -1986,7 +1985,9 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas) { if (m_canvas != nullptr) { +#if !ENABLE_USE_UNIQUE_GLCONTEXT m_context = new wxGLContext(m_canvas); +#endif // !ENABLE_USE_UNIQUE_GLCONTEXT m_timer = new wxTimer(m_canvas); } } @@ -2001,11 +2002,13 @@ GLCanvas3D::~GLCanvas3D() m_timer = nullptr; } +#if !ENABLE_USE_UNIQUE_GLCONTEXT if (m_context != nullptr) { delete m_context; m_context = nullptr; } +#endif // !ENABLE_USE_UNIQUE_GLCONTEXT } void GLCanvas3D::post_event(wxEvent &&event) @@ -2095,6 +2098,7 @@ bool GLCanvas3D::init(bool useVBOs, bool use_legacy_opengl) return true; } +#if !ENABLE_USE_UNIQUE_GLCONTEXT bool GLCanvas3D::set_current() { if ((m_canvas != nullptr) && (m_context != nullptr)) @@ -2102,6 +2106,7 @@ bool GLCanvas3D::set_current() return false; } +#endif // !ENABLE_USE_UNIQUE_GLCONTEXT void GLCanvas3D::set_as_dirty() { @@ -2117,9 +2122,11 @@ void GLCanvas3D::reset_volumes() { if (!m_volumes.empty()) { +#if !ENABLE_USE_UNIQUE_GLCONTEXT // ensures this canvas is current if (!set_current()) return; +#endif // !ENABLE_USE_UNIQUE_GLCONTEXT m_volumes.release_geometry(); m_volumes.clear(); @@ -2514,7 +2521,11 @@ void GLCanvas3D::render() return; // ensures this canvas is current and initialized +#if ENABLE_USE_UNIQUE_GLCONTEXT + if (!_set_current() || !_3DScene::init(m_canvas)) +#else if (!set_current() || !_3DScene::init(m_canvas)) +#endif // ENABLE_USE_UNIQUE_GLCONTEXT return; if (m_force_zoom_to_bed_enabled) @@ -2619,9 +2630,11 @@ void GLCanvas3D::reload_scene(bool force) reset_volumes(); +#if !ENABLE_USE_UNIQUE_GLCONTEXT // ensures this canvas is current if (!set_current()) return; +#endif // !ENABLE_USE_UNIQUE_GLCONTEXT set_bed_shape(dynamic_cast(m_config->option("bed_shape"))->values); @@ -2709,9 +2722,11 @@ void GLCanvas3D::load_gcode_preview(const GCodePreviewData& preview_data, const { if ((m_canvas != nullptr) && (m_print != nullptr)) { +#if !ENABLE_USE_UNIQUE_GLCONTEXT // ensures that this canvas is current if (!set_current()) return; +#endif // !ENABLE_USE_UNIQUE_GLCONTEXT if (m_volumes.empty()) { @@ -3503,8 +3518,10 @@ Point GLCanvas3D::get_local_mouse_position() const void GLCanvas3D::reset_legend_texture() { +#if !ENABLE_USE_UNIQUE_GLCONTEXT if (!set_current()) return; +#endif // !ENABLE_USE_UNIQUE_GLCONTEXT m_legend_texture.reset(); } @@ -3650,13 +3667,27 @@ bool GLCanvas3D::_init_toolbar() return true; } +#if ENABLE_USE_UNIQUE_GLCONTEXT +bool GLCanvas3D::_set_current() +{ + if ((m_canvas != nullptr) && (m_context != nullptr)) + return m_canvas->SetCurrent(*m_context); + + return false; +} +#endif ENABLE_USE_UNIQUE_GLCONTEXT + void GLCanvas3D::_resize(unsigned int w, unsigned int h) { if ((m_canvas == nullptr) && (m_context == nullptr)) return; // ensures that this canvas is current +#if ENABLE_USE_UNIQUE_GLCONTEXT + _set_current(); +#else set_current(); +#endif // ENABLE_USE_UNIQUE_GLCONTEXT ::glViewport(0, 0, w, h); ::glMatrixMode(GL_PROJECTION); @@ -4315,9 +4346,11 @@ int GLCanvas3D::_get_first_selected_volume_id(int object_id) const void GLCanvas3D::_load_print_toolpaths() { +#if !ENABLE_USE_UNIQUE_GLCONTEXT // ensures this canvas is current if (!set_current()) return; +#endif // !ENABLE_USE_UNIQUE_GLCONTEXT if (m_print == nullptr) return; @@ -5427,24 +5460,30 @@ std::vector GLCanvas3D::_parse_colors(const std::vector& col void GLCanvas3D::_generate_legend_texture(const GCodePreviewData& preview_data, const std::vector& tool_colors) { +#if !ENABLE_USE_UNIQUE_GLCONTEXT if (!set_current()) return; +#endif // !ENABLE_USE_UNIQUE_GLCONTEXT m_legend_texture.generate(preview_data, tool_colors); } void GLCanvas3D::_generate_warning_texture(const std::string& msg) { +#if !ENABLE_USE_UNIQUE_GLCONTEXT if (!set_current()) return; +#endif // !ENABLE_USE_UNIQUE_GLCONTEXT m_warning_texture.generate(msg); } void GLCanvas3D::_reset_warning_texture() { +#if !ENABLE_USE_UNIQUE_GLCONTEXT if (!set_current()) return; +#endif // !ENABLE_USE_UNIQUE_GLCONTEXT m_warning_texture.reset(); } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 04da72995..59893368e 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -552,11 +552,17 @@ public: GLCanvas3D(wxGLCanvas* canvas); ~GLCanvas3D(); - wxGLCanvas* widget() { return m_canvas; } +#if ENABLE_USE_UNIQUE_GLCONTEXT + void set_context(wxGLContext* context) { m_context = context; } +#endif // ENABLE_USE_UNIQUE_GLCONTEXT + + wxGLCanvas* get_wxglcanvas() { return m_canvas; } bool init(bool useVBOs, bool use_legacy_opengl); +#if !ENABLE_USE_UNIQUE_GLCONTEXT bool set_current(); +#endif // !ENABLE_USE_UNIQUE_GLCONTEXT void set_as_dirty(); @@ -668,6 +674,9 @@ private: bool _init_toolbar(); +#if ENABLE_USE_UNIQUE_GLCONTEXT + bool _set_current(); +#endif // ENABLE_USE_UNIQUE_GLCONTEXT void _resize(unsigned int w, unsigned int h); BoundingBoxf3 _max_bounding_box() const; diff --git a/src/slic3r/GUI/GLCanvas3DManager.cpp b/src/slic3r/GUI/GLCanvas3DManager.cpp index 41f5ef22a..8720caba5 100644 --- a/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -113,13 +113,29 @@ std::string GLCanvas3DManager::GLInfo::to_string(bool format_as_html, bool exten GLCanvas3DManager::EMultisampleState GLCanvas3DManager::s_multisample = GLCanvas3DManager::MS_Unknown; GLCanvas3DManager::GLCanvas3DManager() +#if ENABLE_USE_UNIQUE_GLCONTEXT + : m_context(nullptr) + , m_current(nullptr) +#else : m_current(nullptr) +#endif // ENABLE_USE_UNIQUE_GLCONTEXT , m_gl_initialized(false) , m_use_legacy_opengl(false) , m_use_VBOs(false) { } +#if ENABLE_USE_UNIQUE_GLCONTEXT +GLCanvas3DManager::~GLCanvas3DManager() +{ + if (m_context != nullptr) + { + delete m_context; + m_context = nullptr; + } +} +#endif // ENABLE_USE_UNIQUE_GLCONTEXT + bool GLCanvas3DManager::add(wxGLCanvas* canvas) { if (canvas == nullptr) @@ -133,6 +149,18 @@ bool GLCanvas3DManager::add(wxGLCanvas* canvas) return false; canvas3D->bind_event_handlers(); + +#if ENABLE_USE_UNIQUE_GLCONTEXT + if (m_context == nullptr) + { + m_context = new wxGLContext(canvas); + if (m_context == nullptr) + return false; + } + + canvas3D->set_context(m_context); +#endif // ENABLE_USE_UNIQUE_GLCONTEXT + m_canvases.insert(CanvasesMap::value_type(canvas, canvas3D)); return true; diff --git a/src/slic3r/GUI/GLCanvas3DManager.hpp b/src/slic3r/GUI/GLCanvas3DManager.hpp index 1a3036f9f..960bb6d2a 100644 --- a/src/slic3r/GUI/GLCanvas3DManager.hpp +++ b/src/slic3r/GUI/GLCanvas3DManager.hpp @@ -52,6 +52,9 @@ class GLCanvas3DManager typedef std::map CanvasesMap; CanvasesMap m_canvases; +#if ENABLE_USE_UNIQUE_GLCONTEXT + wxGLContext* m_context; +#endif // ENABLE_USE_UNIQUE_GLCONTEXT wxGLCanvas* m_current; GLInfo m_gl_info; bool m_gl_initialized; @@ -61,6 +64,9 @@ class GLCanvas3DManager public: GLCanvas3DManager(); +#if ENABLE_USE_UNIQUE_GLCONTEXT + ~GLCanvas3DManager(); +#endif // ENABLE_USE_UNIQUE_GLCONTEXT bool add(wxGLCanvas* canvas); bool remove(wxGLCanvas* canvas); diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index e1566e944..f2d882e22 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -339,13 +339,13 @@ void GLToolbar::do_action(unsigned int item_id) item->set_state(GLToolbarItem::Hover); m_parent.render(); - item->do_action(m_parent.widget()); + item->do_action(m_parent.get_wxglcanvas()); } else { item->set_state(GLToolbarItem::HoverPressed); m_parent.render(); - item->do_action(m_parent.widget()); + item->do_action(m_parent.get_wxglcanvas()); if (item->get_state() != GLToolbarItem::Disabled) { // the item may get disabled during the action, if not, set it back to hover state diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index e7b7f4c94..9c2898558 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -50,7 +50,7 @@ public: Preview(wxNotebook* notebook, DynamicPrintConfig* config, Print* print, GCodePreviewData* gcode_preview_data); virtual ~Preview(); - wxGLCanvas* get_canvas() { return m_canvas; } + wxGLCanvas* get_wxglcanvas() { return m_canvas; } void set_number_extruders(unsigned int number_extruders); void reset_gcode_preview_data(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index bbbdba084..c510258ab 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -520,7 +520,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) : canvas3D->Bind(EVT_GLTOOLBAR_ADD, &priv::on_action_add, this); canvas3D->Bind(EVT_GLCANVAS_VIEWPORT_CHANGED, &priv::on_viewport_changed, this); - preview->get_canvas()->Bind(EVT_GLCANVAS_VIEWPORT_CHANGED, &priv::on_viewport_changed, this); + preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_VIEWPORT_CHANGED, &priv::on_viewport_changed, this); q->Bind(EVT_SLICING_COMPLETED, &priv::on_update_print_preview, this); q->Bind(EVT_PROCESS_COMPLETED, &priv::on_process_completed, this); @@ -893,7 +893,7 @@ void Plater::priv::on_action_add(SimpleEvent&) void Plater::priv::on_viewport_changed(SimpleEvent& evt) { wxObject* o = evt.GetEventObject(); - if (o == preview->get_canvas()) + if (o == preview->get_wxglcanvas()) preview->set_viewport_into_scene(canvas3D); else if (o == canvas3D) preview->set_viewport_from_scene(canvas3D);