Skip to content

Commit

Permalink
video: Try to reset current GL context after touching the renderer.
Browse files Browse the repository at this point in the history
This way if an app tries to render on a background thread, SDL2's GL
renderers will have a chance of working, since they'll be able to set
the context current for that thread.

This does not fix tucnak, for reasons that aren't clear, so that'll
continue to force the software renderer through the quirks mechanism, but
it definitely seems to fix linapple and probably other things, too.

Fixes #104.
Fixes #110.
Fixes #181.
Fixes #155.

(I think.)
  • Loading branch information
icculus committed Sep 1, 2022
1 parent 5642d47 commit aa87f01
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 0 deletions.
31 changes: 31 additions & 0 deletions src/SDL12_compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -5578,6 +5578,26 @@ InitializeOpenGLScaling(const int w, const int h)
}


/* The idea here is that SDL's OpenGL-based renderers always notice if
they aren't using the correct context and attempt to set the correct
context before doing any work, but (at least for X11, and probably
other platforms), the current context is thread-local, and _it's an
error to set a context current if it's already current on another thread_.
So we try to catch every place we call into the renderer and end that
work with a call to this function, which will reset the GL context to NULL,
so if an app tries to render from a background thread, the GL renderer
will be able to set the context, do it's work, and then we reset it right
after. Without this, we either need all apps to render exclusively on
the main thread or fail to draw at all.
This feels risky, but it's better than the alternative! */
static void ResetVideoRendererForThreading(void)
{
if ((VideoRenderer20 != NULL) && (SDL20_GL_GetCurrentContext() != NULL)) {
SDL20_GL_MakeCurrent(NULL, NULL);
}
}

static void HandleInputGrab(SDL12_GrabMode mode);

DECLSPEC SDL12_Surface * SDLCALL
Expand Down Expand Up @@ -6008,6 +6028,10 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12)
VideoSurfacePresentTicks = 0;
VideoSurfaceLastPresentTicks = 0;

if ((flags12 & SDL12_OPENGL) == 0) {
ResetVideoRendererForThreading();
}

return VideoSurface12;
}

Expand Down Expand Up @@ -6322,6 +6346,8 @@ PresentScreen(void)
SDL20_RenderPresent(VideoRenderer20);
VideoSurfaceLastPresentTicks = SDL20_GetTicks();
VideoSurfacePresentTicks = 0;

ResetVideoRendererForThreading();
}

static void
Expand Down Expand Up @@ -6752,6 +6778,7 @@ SDL_WM_ToggleFullScreen(SDL12_Surface *surface)
}
if (retval && VideoRenderer20) {
SDL20_RenderSetLogicalSize(VideoRenderer20, VideoSurface12->w, VideoSurface12->h);
ResetVideoRendererForThreading();
}
}
return retval;
Expand Down Expand Up @@ -7203,6 +7230,8 @@ SDL_CreateYUVOverlay(int w, int h, Uint32 format12, SDL12_Surface *display12)
retval->pixels = hwdata->pixels;
hwdata->dirty = SDL_TRUE;

ResetVideoRendererForThreading();

return retval;
}

Expand Down Expand Up @@ -7298,6 +7327,8 @@ SDL_DisplayYUVOverlay(SDL12_Overlay *overlay12, SDL12_Rect *dstrect12)
VideoSurfacePresentTicks = VideoSurfaceLastPresentTicks + GetDesiredMillisecondsPerFrame(); /* flip it later. */
}

ResetVideoRendererForThreading();

return 0;
}

Expand Down
1 change: 1 addition & 0 deletions src/SDL20_syms.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ SDL20_SYM(int,GL_GetAttribute,(SDL_GLattr a, int *b),(a,b),return)
SDL20_SYM(int,GL_SetSwapInterval,(int a),(a),return)
SDL20_SYM(int,GL_GetSwapInterval,(void),(),return)
SDL20_SYM(SDL_GLContext,GL_CreateContext,(SDL_Window *a),(a),return)
SDL20_SYM(SDL_GLContext,GL_GetCurrentContext,(void),(),return)
SDL20_SYM(int,GL_MakeCurrent,(SDL_Window *a, SDL_GLContext b),(a,b),return)
SDL20_SYM(void,GL_SwapWindow,(SDL_Window *a),(a),)
SDL20_SYM(void,GL_DeleteContext,(SDL_GLContext a),(a),)
Expand Down

0 comments on commit aa87f01

Please sign in to comment.