mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
Overlay draw callback: publish fn+ctx atomically; link it in GL fixtures
Review (#599): fn and ctx were two separate stores read on the render thread, so an unregister could pair a live fn with a NULL ctx. They are now one immutable record behind an acquire/release atomic pointer. The GL fixture runners compile a fixed source list; gpu_gl_renderer.c now calls psx_host_overlay_draw, so every run_gl_*.py links host_overlay.c. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
/* host_overlay.c -- see host_overlay.h. */
|
||||
#include "host_overlay.h"
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* ---- P1: host pause ------------------------------------------------------ */
|
||||
#define PSX_HOST_PAUSE_MAX 8
|
||||
@@ -29,19 +31,35 @@ const char *psx_host_pause_reason(void) {
|
||||
void psx_host_pause_set_refuse_probe(PsxHostPauseRefuseFn fn) { s_pause_refuse = fn; }
|
||||
|
||||
/* ---- P2: overlay draw callback -------------------------------------------- */
|
||||
/* Written on the main thread before the overlay can open, read on the GL
|
||||
* thread; a pointer-sized store, and registration happens once at startup. */
|
||||
static PsxHostOverlayDrawFn volatile s_draw_fn = NULL;
|
||||
static void *volatile s_draw_ctx = NULL;
|
||||
/* Registered on the main thread, read on the render / present thread. The
|
||||
* function and its context are published together as one immutable record
|
||||
* behind an atomic pointer (release on store, acquire on load), so a reader
|
||||
* can never pair a live function with a stale or NULL context. Records are
|
||||
* never freed: registration happens a handful of times per process, and a
|
||||
* reader may still hold the previous record when it is replaced. */
|
||||
typedef struct {
|
||||
PsxHostOverlayDrawFn fn;
|
||||
void *ctx;
|
||||
} PsxHostOverlayDraw;
|
||||
|
||||
static _Atomic(PsxHostOverlayDraw *) s_draw = NULL;
|
||||
|
||||
void psx_host_overlay_set_draw_cb(PsxHostOverlayDrawFn fn, void *ctx) {
|
||||
s_draw_ctx = ctx;
|
||||
s_draw_fn = fn;
|
||||
PsxHostOverlayDraw *rec = NULL;
|
||||
if (fn) {
|
||||
rec = (PsxHostOverlayDraw *)malloc(sizeof(*rec));
|
||||
if (!rec) return;
|
||||
rec->fn = fn;
|
||||
rec->ctx = ctx;
|
||||
}
|
||||
atomic_store_explicit(&s_draw, rec, memory_order_release);
|
||||
}
|
||||
|
||||
int psx_host_overlay_has_draw(void) { return s_draw_fn != NULL; }
|
||||
int psx_host_overlay_has_draw(void) {
|
||||
return atomic_load_explicit(&s_draw, memory_order_acquire) != NULL;
|
||||
}
|
||||
|
||||
void psx_host_overlay_draw(int width, int height) {
|
||||
PsxHostOverlayDrawFn fn = s_draw_fn;
|
||||
if (fn && width > 0 && height > 0) fn(width, height, s_draw_ctx);
|
||||
const PsxHostOverlayDraw *rec = atomic_load_explicit(&s_draw, memory_order_acquire);
|
||||
if (rec && rec->fn && width > 0 && height > 0) rec->fn(width, height, rec->ctx);
|
||||
}
|
||||
|
||||
@@ -95,6 +95,9 @@ def main():
|
||||
if WINDOWS:
|
||||
sections.append("-flto")
|
||||
objs = []
|
||||
# The renderer calls the in-game overlay hook (host_overlay.c) at present.
|
||||
if (src / "host_overlay.c").exists():
|
||||
sources.append(("hov", src / "host_overlay.c"))
|
||||
for name, path in sources:
|
||||
o = dest / (name + ".o")
|
||||
r = run([args.cc, "-std=gnu11", "-O1", "-DPSX_SDL3=1", "-DPSX_NO_DEBUG_TOOLS=1",
|
||||
|
||||
@@ -77,6 +77,9 @@ def main():
|
||||
sources.append(("pth", framework / "runtime/src/present_thread.c"))
|
||||
if (framework / "runtime/src/frame_gen.c").exists():
|
||||
sources.append(("fg", framework / "runtime/src/frame_gen.c"))
|
||||
# The renderer calls the in-game overlay hook (host_overlay.c) at present.
|
||||
if (framework / "runtime/src" / "host_overlay.c").exists():
|
||||
sources.append(("hov", framework / "runtime/src" / "host_overlay.c"))
|
||||
for name, source in sources:
|
||||
if run([compiler / "gcc.exe", "-std=c11", "-O2", "-flto", "-DPSX_SDL3=1",
|
||||
"-DPSX_NO_DEBUG_TOOLS=1", *includes, "-c", source,
|
||||
|
||||
@@ -94,6 +94,9 @@ def main():
|
||||
if WINDOWS:
|
||||
sections.append("-flto")
|
||||
objs = []
|
||||
# The renderer calls the in-game overlay hook (host_overlay.c) at present.
|
||||
if (src / "host_overlay.c").exists():
|
||||
sources.append(("hov", src / "host_overlay.c"))
|
||||
for name, path in sources:
|
||||
o = dest / (name + ".o")
|
||||
r = run([args.cc, "-std=gnu11", "-O1", "-DPSX_SDL3=1", "-DPSX_NO_DEBUG_TOOLS=1",
|
||||
|
||||
@@ -154,6 +154,9 @@ def main():
|
||||
if passes:
|
||||
sections.append("-DPSX_TEST_RENDER_PASSES=1")
|
||||
objs = []
|
||||
# The renderer calls the in-game overlay hook (host_overlay.c) at present.
|
||||
if (framework / "runtime/src" / "host_overlay.c").exists():
|
||||
sources.append(("hov", framework / "runtime/src" / "host_overlay.c"))
|
||||
for name, src in sources:
|
||||
o = dest / (name + ".o")
|
||||
r = run([args.cc, "-std=gnu11", "-O1", "-DPSX_SDL3=1", "-DPSX_NO_DEBUG_TOOLS=1",
|
||||
|
||||
@@ -52,6 +52,9 @@ def main():
|
||||
if (fw/'runtime/src/frame_gen.c').exists():
|
||||
sources.append(('fg',fw/'runtime/src/frame_gen.c'))
|
||||
objects=[]
|
||||
# The renderer calls the in-game overlay hook (host_overlay.c) at present.
|
||||
if (fw/'runtime/src' / "host_overlay.c").exists():
|
||||
sources.append(("hov", fw/'runtime/src' / "host_overlay.c"))
|
||||
for name,source in sources:
|
||||
obj=out/(name+'.o'); run([args.cc,*flags,'-c',source,'-o',obj]); objects.append(obj)
|
||||
if args.hd_pack:
|
||||
|
||||
Reference in New Issue
Block a user