Present thread: one owned swap call; frame-gen fixture builds on MinGW

Both swap paths go through gl_window_swap. The temporal-blending ownership
guard allows the present thread's context (pt_begin only). The frame
generation fixture used setenv, which MinGW lacks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Shokunin
2026-10-06 05:06:07 -07:00
parent 5349824329
commit 084a7c6839
3 changed files with 17 additions and 3 deletions
+6 -2
View File
@@ -8301,6 +8301,10 @@ static int pt_cb_ctx(void *user, int current) {
return 1;
}
/* The one owned swap call: the composing thread's (direct) or the present
* thread's. */
static void gl_window_swap(void) { SDL_GL_SwapWindow(s_win); }
static void *pt_cb_present(void *user, int slot, void *ready) {
(void)user;
if (s_ptp_interval_gen != s_pt_interval_gen) {
@@ -8335,7 +8339,7 @@ static void *pt_cb_present(void *user, int slot, void *ready) {
GL_PRESENT_THREAD_TEST_HOOK(slot);
#endif
void *done = p_glFenceSync(PT_SYNC_GPU_COMMANDS_COMPLETE, 0);
SDL_GL_SwapWindow(s_win);
gl_window_swap();
return done;
}
@@ -8412,7 +8416,7 @@ static void pt_end(void) {
/* The swap: direct, or queued to the present thread. */
static void gl_present_swap(void) {
if (!s_pt_on) { SDL_GL_SwapWindow(s_win); return; }
if (!s_pt_on) { gl_window_swap(); return; }
(void)pt_target_fbo(); /* a frame that never bound 0 still has its slot */
void *ready = p_glFenceSync(PT_SYNC_GPU_COMMANDS_COMPLETE, 0);
glFlush();
@@ -9,9 +9,15 @@ RENDERER = (ROOT / "runtime" / "src" / "gpu_gl_renderer.c").read_text(
encoding="utf-8"
)
assert RENDERER.count("SDL_GL_CreateContext(") == 1, (
# The only second context is the present thread's ([video] present_thread,
# docs/RENDER_THREAD.md), created in pt_begin under the render thread, which
# frame interpolation makes ineligible.
assert RENDERER.count("SDL_GL_CreateContext(") == 2, (
"temporal blending must not create a second GL context"
)
_pt = RENDERER[RENDERER.index("static int pt_begin(void)"):]
_pt = _pt[:_pt.index("\n}\n")]
assert "SDL_GL_CreateContext(" in _pt, "the second GL context belongs to the present thread"
assert "SDL_CreateThread(" not in RENDERER, (
"temporal blending must not create a presentation thread"
)
+4
View File
@@ -254,7 +254,11 @@ int main(int argc, char **argv) {
check(gl_renderer_render_thread_start(2) == 1, "render thread started");
if (pt_mode) check(gl_renderer_present_thread_active(), "present thread started");
if (fg) {
#ifdef _WIN32
_putenv("PSX_FRAME_GEN_FORCE=1");
#else
setenv("PSX_FRAME_GEN_FORCE", "1", 1);
#endif
gl_renderer_set_frame_generation(1);
check(gl_renderer_frame_generation() == 1, "frame generation on");
}