Enable GL on Wayland for wx 3.2+, no vsync.

wxWidgets 3.2+ has experimental `wxGLCanvas` support for Wayland EGL,
enable it for those versions.

The `glXQueryExtensionsString()` method for enabling or disabling vsync
does not work on Wayland currently, so it's disabled.

TODO: Enable/disable vsync on Wayland EGL.

Fix #1028.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
This commit is contained in:
Rafael Kitover 2022-10-21 17:24:46 +00:00
parent 75e46b7117
commit c27d384a53
No known key found for this signature in database
GPG Key ID: 08AB596679D86240
3 changed files with 38 additions and 31 deletions

View File

@ -3707,8 +3707,8 @@ bool MainFrame::BindControls()
#ifdef NO_OGL
rb->Hide();
#endif
#ifdef __WXGTK__
// wxGLCanvas segfaults on Wayland
#if defined(__WXGTK__) && !wxCHECK_VERSION(3, 2, 0)
// wxGLCanvas segfaults on Wayland before wx 3.2
if (wxGetApp().UsingWayland()) {
rb->Hide();
}

View File

@ -2176,39 +2176,44 @@ void GLDrawingPanel::DrawingPanelInit()
glClearColor(0.0, 0.0, 0.0, 1.0);
// non-portable vsync code
#if defined(__WXGTK__)
static PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT = NULL;
static PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = NULL;
static PFNGLXSWAPINTERVALMESAPROC glXSwapIntervalMESA = NULL;
// TODO: Use Wayland EGL equivalent to enable/disable vsync.
if (!IsItWayland()) {
static PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT = NULL;
static PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = NULL;
static PFNGLXSWAPINTERVALMESAPROC glXSwapIntervalMESA = NULL;
auto display = GetX11Display();
// These wayland checks don't work.
auto display = IsItWayland() ? 0 : GetX11Display();
auto default_screen = IsItWayland() ? 0 : DefaultScreen(display);
char* glxQuery = (char*)glXQueryExtensionsString(display, DefaultScreen(display));
char* glxQuery = (char*)glXQueryExtensionsString(display, default_screen);
if (strstr(glxQuery, "GLX_EXT_swap_control") != NULL)
{
glXSwapIntervalEXT = reinterpret_cast<PFNGLXSWAPINTERVALEXTPROC>(glXGetProcAddress((const GLubyte*)"glXSwapIntervalEXT"));
if (glXSwapIntervalEXT)
glXSwapIntervalEXT(glXGetCurrentDisplay(), glXGetCurrentDrawable(), vsync);
else
systemScreenMessage(_("Failed to set glXSwapIntervalEXT"));
}
if (strstr(glxQuery, "GLX_SGI_swap_control") != NULL)
{
glXSwapIntervalSGI = reinterpret_cast<PFNGLXSWAPINTERVALSGIPROC>(glXGetProcAddress((const GLubyte*)("glXSwapIntervalSGI")));
if (strstr(glxQuery, "GLX_EXT_swap_control") != NULL)
{
glXSwapIntervalEXT = reinterpret_cast<PFNGLXSWAPINTERVALEXTPROC>(glXGetProcAddress((const GLubyte*)"glXSwapIntervalEXT"));
if (glXSwapIntervalEXT)
glXSwapIntervalEXT(glXGetCurrentDisplay(), glXGetCurrentDrawable(), vsync);
else
systemScreenMessage(_("Failed to set glXSwapIntervalEXT"));
}
if (strstr(glxQuery, "GLX_SGI_swap_control") != NULL)
{
glXSwapIntervalSGI = reinterpret_cast<PFNGLXSWAPINTERVALSGIPROC>(glXGetProcAddress((const GLubyte*)("glXSwapIntervalSGI")));
if (glXSwapIntervalSGI)
glXSwapIntervalSGI(vsync);
else
systemScreenMessage(_("Failed to set glXSwapIntervalSGI"));
}
if (strstr(glxQuery, "GLX_MESA_swap_control") != NULL)
{
glXSwapIntervalMESA = reinterpret_cast<PFNGLXSWAPINTERVALMESAPROC>(glXGetProcAddress((const GLubyte*)("glXSwapIntervalMESA")));
if (glXSwapIntervalSGI)
glXSwapIntervalSGI(vsync);
else
systemScreenMessage(_("Failed to set glXSwapIntervalSGI"));
}
if (strstr(glxQuery, "GLX_MESA_swap_control") != NULL)
{
glXSwapIntervalMESA = reinterpret_cast<PFNGLXSWAPINTERVALMESAPROC>(glXGetProcAddress((const GLubyte*)("glXSwapIntervalMESA")));
if (glXSwapIntervalMESA)
glXSwapIntervalMESA(vsync);
else
systemScreenMessage(_("Failed to set glXSwapIntervalMESA"));
if (glXSwapIntervalMESA)
glXSwapIntervalMESA(vsync);
else
systemScreenMessage(_("Failed to set glXSwapIntervalMESA"));
}
}
#elif defined(__WXMSW__)
typedef const char* (*wglext)();

View File

@ -358,10 +358,12 @@ bool wxvbamApp::OnInit() {
load_opts();
// wxGLCanvas segfaults under wayland
// wxGLCanvas segfaults under wayland before wx 3.2
#if defined(__WXGTK__) && !wxCHECK_VERSION(3, 2, 0)
if (UsingWayland() && gopts.render_method == RND_OPENGL) {
gopts.render_method = RND_SIMPLE;
}
#endif
// process command-line options
for (size_t i = 0; i < pending_optset.size(); i++) {