Skip to content

[pull] master from GaijinEntertainment:master#990

Merged
pull[bot] merged 7 commits into
forksnd:masterfrom
GaijinEntertainment:master
May 13, 2026
Merged

[pull] master from GaijinEntertainment:master#990
pull[bot] merged 7 commits into
forksnd:masterfrom
GaijinEntertainment:master

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented May 13, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

profelis and others added 7 commits May 13, 2026 18:24
Replace the sync glReadPixels in record_tick with a ring of N
GL_PIXEL_PACK_BUFFER PBOs (default 4, range [2,8], per-recording
override via record_start args.pbo_count).

Each tick now does two things back to back:
- write side: kick off glReadPixels into pbos[K%N] with a null offset
  so the GPU returns immediately, then stash the frame's delay_ms in
  a parallel ring slot.
- read side (once frames_seen >= N): map pbos[(K-N+1)%N] (oldest in
  flight, GPU has long since finished it), feed the pixels to
  stbi_apng_frame with the matching delay, glUnmapBuffer.

record_stop drains the remaining N-1 in-flight buffers in order via
the same harvest helper, then glDeleteBuffers and resets state. The
encoder worker thread inside the C++ writer is unchanged — only the
GL→CPU path was the bottleneck at 1280x720+.

While here, drop the PNG zlib compression level from stbi's default
of 8 to 4 at record_start time. Level 8 caps the single encoder
thread around 25-27 fps on a 1280x720 stream; level 4 is 2-3x faster
per frame with a minor file-size cost, which is the right tradeoff
for tutorial-style recordings of bounded duration. The comment at
the call site flags this as a tutorial-friendly baseline so it's
clear where to promote it to a `compression_level` arg if a future
caller needs lossless-ish capture instead.

Net effect on a 1024x720 / 30fps / 16.8s widgets_tour recording:
448 frames, 0 dropped (was 128/443 = 29% on the sync path).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
rst: add property assignment operator for function name handling
Five fixes from the round-1 review on PR #2645.

Copilot #1 — Leak on glGenBuffers id==0 early return:
  The `id == 0u` early return path now glDeleteBuffers the partial
  allocation and `delete pbos` before returning the error, so a
  pathological driver doesn't leak GL buffers + the local array.

Copilot #2 — stbi_write_set_png_compression_level was global mutation:
  RecorderState gains `prev_png_level`. record_start captures the
  current level via `stbi_write_get_png_compression_level()` before
  setting it to 4, then record_stop restores it. The writer-open-failure
  cleanup path also restores. Screenshot and any unrelated PNG writes
  are no longer permanently throttled to the tutorial-friendly level.

Copilot #3 — glUnmapBuffer return value ignored:
  harvest_one_pbo now captures glUnmapBuffer's return; GL_FALSE means
  the driver invalidated the buffer contents while it was mapped, so
  treat it as a harvest failure rather than letting potentially junk
  pixels into the apng stream.

Copilot #4 — record_stop drain comment was wrong:
  The previous comment claimed failures were "logged via the dropped
  counter", but `stbi_apng_dropped()` only reports encoder queue
  overflows inside the writer — not GL-side harvest failures. Comment
  now states behaviour accurately: a failed drain breaks the loop and
  the resulting `frames` count reflects what actually made it to disk.

aleksisch — unsafe audit + narrowing:
  Several `unsafe { ... }` blocks wrapped calls that don't actually
  need unsafe in daslang (int-only arg lists, GLenum-only arg lists,
  null-data variants of GL buffer functions). Drops:
    - stbi_write_set_png_compression_level (int arg only)
    - stbi_apng_dropped / stbi_apng_end (void? writer, no raw ptr exposed)
    - glBufferData(target, size, null, usage) (null data variant)
    - glUnmapBuffer (GLenum arg, GLboolean return)
    - glReadPixels(..., null) into bound PBO (null data variant)
  Remaining unsafe is narrowed from `unsafe { ... }` to `unsafe(expr)`
  on the bare expressions that genuinely need it (every `addr(pbos[0])`
  call returning a raw pointer, and `stbi_apng_frame` which takes a
  raw `void*` pixel pointer). A general lint rule for redundant
  `unsafe` is out of scope for this PR — separate followup.

While there, two STYLE005 lint hits fixed by switching to postfix
`break if`/`return if`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…bo-ring-capture

dasOpenGL: async PBO ring for APNG capture
platform.h: disable warnings for inline static atomic type size issues
@pull pull Bot locked and limited conversation to collaborators May 13, 2026
@pull pull Bot added the ⤵️ pull label May 13, 2026
@pull pull Bot merged commit 4187f9b into forksnd:master May 13, 2026
@pull pull Bot had a problem deploying to github-pages May 13, 2026 20:58 Error
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants