Ensure that we call eglSwapInterval() for the correct context
Calling it from the frame callback might change the swap interval for the wrong context if the active context got changed in the meanwhile, but by the time SwapBuffers() is called the correct context must be set. Doing it there also allows to unify X11 and Wayland code branches. See #24014. (cherry picked from commit 64afa9d96341f3696ba5311d36fd3a82f7c9de77)
This commit is contained in:
parent
414faff190
commit
45ac25826b
@ -453,24 +453,6 @@ void wxGLCanvasEGL::OnWLFrameCallback()
|
|||||||
#ifdef GDK_WINDOWING_WAYLAND
|
#ifdef GDK_WINDOWING_WAYLAND
|
||||||
wxLogTrace(TRACE_EGL, "In frame callback handler for %p", this);
|
wxLogTrace(TRACE_EGL, "In frame callback handler for %p", this);
|
||||||
|
|
||||||
if ( !gs_alreadySetSwapInterval.count(this) )
|
|
||||||
{
|
|
||||||
// Ensure that eglSwapBuffers() doesn't block, as we use the surface
|
|
||||||
// callback to know when we should draw ourselves already.
|
|
||||||
if ( eglSwapInterval(m_display, 0) )
|
|
||||||
{
|
|
||||||
wxLogTrace(TRACE_EGL, "Set EGL swap interval to 0 for %p", this);
|
|
||||||
|
|
||||||
// It shouldn't be necessary to set it again.
|
|
||||||
gs_alreadySetSwapInterval.insert(this);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wxLogTrace(TRACE_EGL, "eglSwapInterval(0) failed for %p: %#x",
|
|
||||||
this, eglGetError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_readyToDraw = true;
|
m_readyToDraw = true;
|
||||||
g_clear_pointer(&m_wlFrameCallbackHandler, wl_callback_destroy);
|
g_clear_pointer(&m_wlFrameCallbackHandler, wl_callback_destroy);
|
||||||
SendSizeEvent();
|
SendSizeEvent();
|
||||||
@ -803,15 +785,40 @@ void wxGLCanvasEGL::FreeDefaultConfig()
|
|||||||
|
|
||||||
bool wxGLCanvasEGL::SwapBuffers()
|
bool wxGLCanvasEGL::SwapBuffers()
|
||||||
{
|
{
|
||||||
|
// Before doing anything else, ensure that eglSwapBuffers() doesn't block:
|
||||||
|
// under Wayland we don't want it to because we use the surface callback to
|
||||||
|
// know when we should draw anyhow and with X11 it blocks for up to a
|
||||||
|
// second when the window is entirely occluded and because we can't detect
|
||||||
|
// this currently (our IsShownOnScreen() doesn't account for all cases in
|
||||||
|
// which this happens) we must prevent it from blocking to avoid making the
|
||||||
|
// entire application completely unusable just because one of its windows
|
||||||
|
// using wxGLCanvas got occluded or unmapped (e.g. due to a move to another
|
||||||
|
// workspace).
|
||||||
|
if ( !gs_alreadySetSwapInterval.count(this) )
|
||||||
|
{
|
||||||
|
// Ensure that eglSwapBuffers() doesn't block, as we use the surface
|
||||||
|
// callback to know when we should draw ourselves already.
|
||||||
|
if ( eglSwapInterval(m_display, 0) )
|
||||||
|
{
|
||||||
|
wxLogTrace(TRACE_EGL, "Set EGL swap interval to 0 for %p", this);
|
||||||
|
|
||||||
|
// It shouldn't be necessary to set it again.
|
||||||
|
gs_alreadySetSwapInterval.insert(this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxLogTrace(TRACE_EGL, "eglSwapInterval(0) failed for %p: %#x",
|
||||||
|
this, eglGetError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GdkWindow* const window = GTKGetDrawingWindow();
|
GdkWindow* const window = GTKGetDrawingWindow();
|
||||||
#ifdef GDK_WINDOWING_X11
|
#ifdef GDK_WINDOWING_X11
|
||||||
if (wxGTKImpl::IsX11(window))
|
if (wxGTKImpl::IsX11(window))
|
||||||
{
|
{
|
||||||
if ( !IsShownOnScreen() )
|
if ( !IsShownOnScreen() )
|
||||||
{
|
{
|
||||||
// Trying to draw on a hidden window is useless and can actually be
|
// Trying to draw on a hidden window is useless.
|
||||||
// harmful if the compositor blocks in eglSwapBuffers() in this
|
|
||||||
// case, so avoid it.
|
|
||||||
wxLogTrace(TRACE_EGL, "Window %p is hidden, not drawing", this);
|
wxLogTrace(TRACE_EGL, "Window %p is hidden, not drawing", this);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user