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.
This commit is contained in:
Joshua Wise 2023-01-24 03:02:40 -05:00 committed by Lane.Wei
parent a082ce50ed
commit aa2d692910
3 changed files with 16 additions and 0 deletions

View File

@ -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)
{

View File

@ -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;

View File

@ -39,6 +39,7 @@
#include <wx/textctrl.h>
#include <wx/splash.h>
#include <wx/fontutil.h>
#include <wx/glcanvas.h>
#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<float>(canvas_size.get_width()), static_cast<float>(canvas_size.get_height()));
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", start to init opengl";