Skip to content

perf(core): drop dead 1x1 placeholder upload in the image path#103

Merged
chiefcll merged 1 commit into
mainfrom
perf/texture-upload-reduce-redundant-work
Jun 13, 2026
Merged

perf(core): drop dead 1x1 placeholder upload in the image path#103
chiefcll merged 1 commit into
mainfrom
perf/texture-upload-reduce-redundant-work

Conversation

@chiefcll

@chiefcll chiefcll commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

What changed

WebGlCtxTexture.onLoadRequest began with a texImage2D(1×1, null) + setTextureMemUse(...), then — with no await in between — every real branch (ImageBitmap / ImageData / HTMLImageElement / Uint8Array / compressed) fully re-uploads the texture, overwriting both. So no frame could ever render the placeholder, and the empty-texture (tdata === null) branch already does its own 1×1 upload.

Removing it saves one texImage2D GL call + one setTextureMemUse (LRU-set mutation + threshold check) per texture upload.

Why

Per the engine's TV cost model, GL calls are CPU charged into the GPU command-buffer, so this is real per-upload CPU removed. Visual output is byte-identical by construction — the deleted upload was always overwritten with no intervening frame. SubTexture/RenderTexture override onLoadRequest and are unaffected.

Reviewer notes

  • The removed 1×1 was only ever a placeholder; the tdata === null branch is self-sufficient. Verified there's no await between texture creation and the real upload, so no intermediate frame can observe it.
  • Not pursued: splitting createNativeCtxTexture from texImage2D across frames — it relocates ~10µs of cheap GL calls while the dominant texImage2D stays atomic in one frame, at the cost of +1 frame latency and state-machine complexity.

Testing

  • Full suite: 246/246 across 26 files; tsc --build clean.
  • Visual output unchanged by construction; pnpm test:visual (Docker) is the belt-and-suspenders check if desired.

🤖 Generated with Claude Code

WebGlCtxTexture.onLoadRequest began with a texImage2D(1x1, null) +
setTextureMemUse, then — with no `await` in between — every real branch
(ImageBitmap / ImageData / HTMLImageElement / Uint8Array / compressed)
fully (re)uploads the texture, overwriting both. No frame can render the
placeholder, and the empty-texture (`tdata === null`) branch does its own
1x1 upload.

Removing it saves one texImage2D GL call + one setTextureMemUse (LRU-set
mutation + threshold check) per texture upload. On the TV cost model GL
calls are CPU charged into the GPU command buffer, so this is real
per-upload CPU removed. Visual output is byte-identical by construction.
SubTexture/RenderTexture override onLoadRequest and are unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@chiefcll chiefcll force-pushed the perf/texture-upload-reduce-redundant-work branch from c5906ee to 8cf06bb Compare June 13, 2026 12:39
@chiefcll chiefcll changed the title perf(core): cut redundant texture-upload work in the image path perf(core): drop dead 1x1 placeholder upload in the image path Jun 13, 2026
@chiefcll chiefcll merged commit a23caf8 into main Jun 13, 2026
1 check passed
@chiefcll chiefcll deleted the perf/texture-upload-reduce-redundant-work branch June 13, 2026 12:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant