From 0e343b4fc40ea8f6d6fcf82145cd4af7319c7889 Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Tue, 24 Jan 2023 03:02:40 -0500 Subject: [PATCH] Linux: ensure that a GLCanvas3D can become active before attempting to start OpenGL (fixes #1149) On Linux, GLEW requires (at least, in EGL land) that an OpenGL context be active before glew_Init is called -- otherwise, GLEW doesn't know what extension symbols to look up. If glew_Init fails, then some symbols elsewhere will not exist, and the app will shortly crash. We work around this by detecting if we're actually ready for postinit, and if not, resetting the flag so that wxEVT_IDLE will cause us to try again later, when the window hopefully has gone into the foreground and is ready to be used. --- src/slic3r/GUI/GLCanvas3D.cpp | 3 +++ src/slic3r/GUI/GLCanvas3D.hpp | 2 ++ src/slic3r/GUI/GUI_App.cpp | 11 +++++++++++ 3 files changed, 16 insertions(+) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 808567c237c..b08d2536844 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1706,6 +1706,9 @@ float GLCanvas3D::get_collapse_toolbar_height() return collapse_toolbar.is_enabled() ? collapse_toolbar.get_height() : 0; } +bool GLCanvas3D::make_current_for_postinit() { + return _set_current(); +} void GLCanvas3D::render(bool only_init) { diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 47354060a3b..82a20b2d194 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -1043,6 +1043,8 @@ public: // If the Z screen space coordinate is not provided, a depth buffer value is substituted. Vec3d _mouse_to_3d(const Point& mouse_pos, float* z = nullptr); + bool make_current_for_postinit(); + private: bool _is_shown_on_screen() const; diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 316797f823b..a66d6faf5f4 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include "libslic3r/Utils.hpp" #include "libslic3r/Model.hpp" @@ -1016,6 +1017,16 @@ void GUI_App::post_init() mainframe->select_tab(size_t(MainFrame::tp3DEditor)); plater_->select_view_3D("3D"); //BBS init the opengl resource here +#ifdef __linux__ + if (!plater_->canvas3D()->get_wxglcanvas()->IsShownOnScreen() || + !plater_->canvas3D()->make_current_for_postinit()) { + /* The canvas3d didn't actually exist (and therefore, there is + * no current EGL context) -- try again later, I guess. + */ + m_post_initialized = false; + return; + } +#endif Size canvas_size = plater_->canvas3D()->get_canvas_size(); wxGetApp().imgui()->set_display_size(static_cast(canvas_size.get_width()), static_cast(canvas_size.get_height())); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", start to init opengl";