Repository navigation
Rasterize headless frames only when their pixels are read - #602
Merged
Merged
Conversation
ImGuiAppHarness now defers each frame's rasterization until Capture() or Target reads it. Stepping hands the draw data to SoftwareRenderer, which draws it on read; a step discards an unread frame before NewFrame reuses its draw data. Changing a texture or render target while a frame is pending draws that frame first, so a read always shows the last frame stepped, drawn with the textures it was submitted with. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TB1B6ZUvpNiBAjpfYU42K2
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TB1B6ZUvpNiBAjpfYU42K2
|
This was referenced Oct 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Requested by Matt · project thread
Before:
ImGuiAppHarness.Steprasterized every frame on the CPU, whether or not a test ever looked at it. Profiling ImageGui's UI suite (ktsu-dev/ImageGui#76) put about 95% of its time there.After: a stepped frame is rasterized only when its pixels are read, through
Capture()orTarget. Stepping is cheap; a read pays for one frame. What a read sees is unchanged: every frame clears the whole target, so the last frame stepped is the only one that matters, and it is drawn with the textures it was submitted with.How:
HeadlessImGuiContext.EndFrameDeferredhands the draw data toSoftwareRenderer, which draws it lazily from theTargetgetter. The harness discards an unread frame before the nextNewFrame, which is when ImGui reuses that draw data, and before disposing the context. Any texture or render-target mutation while a frame is pending (UpdateTexture,DeleteTexture, render target clear/draw/resize/delete) draws the pending frame first, so a texture changed between a step and a read does not repaint the stepped frame.SoftwareRendererused standalone (RenderDrawData,Clear) stays eager.One caveat, documented on
Targetand in the harness README: aBitmap32held fromTargetacross a step still shows the frame it was read on. Nothing in this repository does that.DeferredRasterizationTestspins it: unread frames are never rasterized and a frame read twice is rasterized once; a read shows the last frame stepped; a texture updated, or a render target cleared, between step and read is drawn as submitted. Every suite in the solution passes locally in Release.Measured locally (Release, same container, wall-clock per suite)
🤖 Generated with Claude Code
https://claude.ai/code/session_01TB1B6ZUvpNiBAjpfYU42K2