GL: forget the bezel texture when the renderer shuts down

The session reset clears g_bezel_path, which only stops the next load.
gl_renderer_shutdown() deleted the context but kept s_bezel_tex, and
present_bezel() draws whenever that name is nonzero, so a lobby rematch
would bind the previous session's texture name in its new context.
Shutdown now drops it through gl_renderer_set_bezel(NULL, 0, 0) while
the context is still current. Only a soft return to the lobby and
process exit shut the renderer down.

The source guard checks the shutdown call and set_bezel's NULL path.
MOD_PACKAGES.md says what each half of the bezel reset does and gives
the exact reset values for the adaptive cap and the native pacing rate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Shokunin
2026-09-28 20:05:17 -07:00
parent 06c3615934
commit 84d718f981
3 changed files with 29 additions and 3 deletions
+9 -3
View File
@@ -541,13 +541,13 @@ offline rematch. The rest of the table is defensive, for the state listed here.
| State | Setter | Reset to | When |
|---|---|---|---|
| Fit / capped adaptive aspect | `psx_mod_set_adaptive_display_aspect` | off | every session |
| Fit / capped adaptive aspect | `psx_mod_set_adaptive_display_aspect` | off, cap 16:9 | every session |
| World-scene predicate | `psx_mod_set_world_scene_predicate` | NULL | every session |
| Retained-scene predicate | `psx_mod_set_retained_scene_predicate` | NULL | every session |
| Adaptive backdrop preload | `psx_mod_set_adaptive_backdrop_preload` | 0 | every session |
| Bezel artwork | `psx_mod_set_bezel_artwork` | none | every session |
| Bezel artwork | `psx_mod_set_bezel_artwork` | none (see below) | every session |
| Frame-interpolation blend mode | `psx_mod_set_frame_interpolation_blend` | default | every session |
| Native VBlank pacing | `psx_mod_set_native_vblank_rate` | off | every session |
| Native VBlank pacing and its rate | `psx_mod_set_native_vblank_rate` | off, 0 | every session |
| Frame period, if native VBlank pacing was on | `psx_mod_set_native_vblank_rate` | first-session value | later sessions |
| Frame interpolation and its rate | `psx_mod_set_frame_interpolation` | first-session value | later sessions |
| Vsync forced off | `psx_mod_set_frame_interpolation`, `psx_mod_set_native_vblank_rate` | first-session value | later sessions |
@@ -563,6 +563,12 @@ soft-returns, behaves exactly as without the reset. The RAM request matters on
a rematch because `memory_init()` latches the requested geometry again at every
boot, including the rematch's.
Bezel artwork has two parts. The reset clears the artwork path, so the next
session start loads nothing unless its own activation selects artwork again.
The OpenGL renderer drops the loaded texture itself when it shuts down, which
happens when a session ends by returning to the lobby (and at process exit),
so a rematch never draws the previous session's artwork in its new context.
Not reset, and why:
- The **fixed display aspect** (`psx_mod_set_fixed_display_aspect`) and the
+4
View File
@@ -3146,6 +3146,10 @@ void gl_renderer_shutdown(void) {
if (s_ctx) {
for (unsigned i = 1; i < 65536u; ++i)
if (s_bank_tex[i]) glDeleteTextures(1, &s_bank_tex[i]);
/* Bezel artwork belongs to the session that loaded it: a lobby
* rematch creates a new context and loads its own artwork (or none),
* and present_bezel() must not bind this name in that context. */
gl_renderer_set_bezel(NULL, 0, 0);
}
memset(s_bank_tex, 0, sizeof s_bank_tex);
s_selected_bank_tex = s_tb_bank_tex = 0;
@@ -83,6 +83,22 @@ for reset in (
):
assert reset in later, f"later-session reset is missing: {reset}"
# Bezel artwork: clearing g_bezel_path only stops the next load. The loaded
# texture must not outlive the session's GL context either, or a rematch would
# bind the stale name in its new context (present_bezel() draws whenever it is
# nonzero). Only a soft return and process exit shut the renderer down.
GL = (ROOT / "runtime" / "src" / "gpu_gl_renderer.c").read_text(encoding="utf-8")
shutdown = GL[GL.index("void gl_renderer_shutdown(void) {"):]
shutdown = shutdown[:shutdown.index("\n}\n")]
live_ctx = shutdown[shutdown.index("if (s_ctx) {"):shutdown.index("SDL_GL_DeleteContext(s_ctx);")]
assert "gl_renderer_set_bezel(NULL, 0, 0);" in live_ctx, \
"gl_renderer_shutdown() must drop the bezel texture while its context is current"
set_bezel = GL[GL.index("int gl_renderer_set_bezel(const void *rgba, int w, int h) {"):]
assert set_bezel.index("if (s_bezel_tex) { glDeleteTextures(1, &s_bezel_tex); s_bezel_tex = 0; }") < \
set_bezel.index("if (!rgba || w <= 0 || h <= 0) return 1;"), \
"gl_renderer_set_bezel(NULL, ...) must delete and forget the texture"
assert "if (!s_bezel_tex || ww <= 0 || wh <= 0) return;" in GL
# First-boot session block: reset immediately before activation.
assert "reset_mod_owned_presentation();\n mod_runtime_activate_plugins();" in MAIN, \
"reset must run immediately before mod activation"