D952: macOS black window when started with the display asleep - VSync through CGL, not SDL3's display-link wait

This commit is contained in:
James Dansereau committed 2026-10-13 14:02:56 -04:00
1 parent af5e75ccbf
commit a9feb0960f
4 files changed
+61

No files matched your search

+1
View File
@@ -463,6 +463,7 @@ D644,FIXED,File-select royal crest drew on an opaque dark square (#146):,"FIXED
D645,FIXED,"Original 1.1: F10 ""Invert look"" did not invert vertical look (#145 a):",FIXED 2026-10-12 (F10 row and watch row synced in Original; maintainer-verified)
D646,FIXED,"F10 dropdown popup drew over the hint/tooltip panel (popup bounded by the screen edge, not the settings box) —",FIXED 2026-10-12 (ddGeom bounded to the box; maintainer-verified)
D951,OPEN,"v0.6.0 release gate: Windows golden sweep flags are timing noise in the test, not rendering changes —",OPEN (test-side; 2026-10-13)
D952,FIXED,"macOS: black window, no frame, when the game starts while the display is asleep (SDL3 Cocoa VSync waits forever on a CVDisplayLink that never started) —","FIXED 2026-10-13 (port-only, gfx_sdl2.cpp; Mac A/B:"
D607,OPEN,Address model unified into one header:,DONE 2026-10-07 (macos branch; Windows identity gate:
D608,FIXED,D34 ANIM_DATA_x re-basing guard in assets/animationtable_data.h was __x86_64__-only:,"FIXED 2026-10-07 (macos branch; mechanical guard widening, arm64 link clean)"
D609,FIXED,macOS arm64 SIGKILL at exec:,"FIXED 2026-10-07 (macos branch; probe-confirmed; arm64 keeps the 4 GiB pagezero, floor 11.0)"
1 # GENERATED by tools_pc/gen_findings_index.py -- do not hand-edit.
463 D645
464 D646
465 D951
466 D952
467 D607
468 D608
469 D609
+15
View File
@@ -874,6 +874,7 @@ covers D24–D69; the log continues in §H (D32 procedure, D70–D121).
| D645 | **Original 1.1: F10 "Invert look" did not invert vertical look (#145 a): D605 flipped the move stick; the game's own Look up/down drives C-button/aim pitch** — full `## D645` entry at file tail | FIXED 2026-10-12 (F10 row and watch row synced in Original; maintainer-verified) |
| D646 | **F10 dropdown popup drew over the hint/tooltip panel (popup bounded by the screen edge, not the settings box)** — full `## D646` entry at file tail | FIXED 2026-10-12 (`ddGeom` bounded to the box; maintainer-verified) |
| D951 | **v0.6.0 release gate: Windows golden sweep flags are timing noise in the test, not rendering changes** — full `## D951` entry at file tail | OPEN (test-side; 2026-10-13) |
| D952 | **macOS: black window, no frame, when the game starts while the display is asleep (SDL3 Cocoa VSync waits forever on a CVDisplayLink that never started)** — full `## D952` entry at file tail | FIXED 2026-10-13 (port-only, `gfx_sdl2.cpp`; Mac A/B: unfixed 3/3 hang, fixed 0/5) |
Phase 2 replaced the Phase-1 demo loop with the real `mainproc()` on real OS
threads, compiled GE's real `src/sched.c`, and brought in PD's fast3d software
@@ -21999,3 +22000,17 @@ FpsCap = 60'`: 20/21 PASS; statue REGRESSION (4.66%, frame 900).
**Owed (test side only).** (1) verify.sh should pin `FpsCap = 60` in its ini itself, since the goldens are 60 fps captures; (2) a flagged level should be re-run once before it counts as a regression, or the first run should be discarded as warm-up. No game-code change.
**Status.** OPEN, test-side.
## D952: macOS first-start black window = SDL3 VSync waiting on a CVDisplayLink that never started (display asleep) — FIXED 2026-10-13
**Symptom.** "If the window stays black on the very first start, close it and start it again" (v0.6.0 known issue): 4 hangs on 10-12 and 2 of 13 cold first launches on 10-13, always the first launch after the Mac had sat idle (which is when a new CI build arrives, so it looked like "first launch of a new binary").
**Evidence.** Hung run (`kernel heartbeat: no frame rendered`, frames=0) sampled with `sample`: the D481 render worker sits in `portRenderGfxTask -> Cocoa_GL_SwapWindow -> SDL_WaitConditionTimeoutNS -> __psynch_cvwait`; the scheduler, `amMain` (`src/audi.c` reply wait) and `bossMainloop` only wait behind it. The process has NO `CVDisplayLink` thread; a healthy run has one. SDL 3.4.14 (`SDL_cocoaopengl.m`): with a swap interval set, `Cocoa_GL_SwapWindow` waits on a condition that only the display-link callback signals, with no timeout; the link is created and started once, in `initWithFormat`, from the active displays.
**Trigger (deterministic).** `pmset displaysleepnow`, then launch: unfixed download 3/3 hang. Re-signing the binary (new cdhash) with the display awake: 0/10. The "new binary" correlation was the idle gap before it.
**Fix (`port/fast3d/gfx_sdl2.cpp`, `__APPLE__` only).** SDL's swap interval stays 0, so SDL's swap never waits; VSync is set on the context with `CGLSetParameter(kCGLCPSwapInterval)` (as SDL2 did on macOS), which blocks in `flushBuffer` on the driver's own refresh. `get_swap_interval` returns the CGL value, so D578/D600 pacing sees the same interval as before. Logs `SDL: swap interval N via CGL (read back N)`.
**Verified (Mac M3, macOS 15.6.1, fix built with the CI recipe, run against the download's own SDL 3.4.14 dylibs).** Display asleep: fixed 0/5 hang. Display awake: 60.0 presents/s as before; VSync on/off read back 1/0 from CGL. 21-level sweep (mac_sweep.sh, fixed binary): 21/21 OK. Windows build clean; Windows/Linux code paths unchanged (`#else` = the old lines).
**Status.** FIXED.
+2
View File
@@ -676,6 +676,8 @@ through a converter or a runtime bswap fixup reads scrambled.
- **CPU-built RDP triangles need float vertices, not `Vtx` (D245).** Where GE builds RDP edge/texture coefficients on the CPU (sky/water), 32-bit S/T and positions are normal; squeezing them through s16 `tc`/`ob` costs visible precision on horizon-scale geometry. Use `G_FLOATVTX_EXT` (`port/include/floatvtx.h`).
- **A first-run-only preset is skipped forever by any earlier launch that created the ini, and window keys are not an "untouched" signal (D283).** Seeding values *before* `configLoad()` only works when no `ge007.ini` exists; one launch in a different environment (SteamOS Desktop Mode has no `STEAMOS`) writes a plain ini and the preset never runs. Apply presets *after* the load, record a one-shot flag key, and gate on keys the user must change deliberately (`Video.Fullscreen`, `Window.Maximized`) — `Window.Width/Height` are rewritten from the live window on every clean exit (`videoSaveWindowState`), so "still at default" never holds for them.
**SDL3 on macOS: a GL swap with VSync can wait forever (D952).** SDL3's Cocoa backend implements the GL swap interval itself: `SDL_GL_SwapWindow` waits, with no timeout, for a tick from a `CVDisplayLink` that SDL creates and starts once, with the context. If that link never runs (seen when the game starts while the display is asleep), the first swap never returns: black window, zero frames, every other thread waiting behind the render thread. Tells: `sample` shows `Cocoa_GL_SwapWindow -> SDL_WaitCondition*` on the render thread and the process has no `CVDisplayLink` thread. Fix pattern: leave SDL's interval at 0 and set `kCGLCPSwapInterval` on the context with `CGLSetParameter`, which waits in the driver (SDL2's behaviour). Reproduce with `pmset displaysleepnow` before launching.
## D. N64 hardware idioms fast3d does not emulate
- **Appending a port-owned 2D overlay to the game frame: hook inside