Repository navigation
Close the O= finding: an object is read once, so it is placed once - #9
Merged
Merged
Conversation
One object per frame, every tile placed out of it at an offset, was tried a second time --
against kitty this time, since the first attempt had only Ghostty's silence to go on. kitty
draws it exactly as Ghostty does, which is to say it does not, and that is what identified
the cause: the spec has the terminal "read the data from the memory object and then unlink
and close it". One read is all an object gets. A frame that places ninety-one tiles out of
one object makes ninety-one commands of it, the first consumes the name, and every later
`shm_open` finds nothing -- so the frame's first tile draws and the screen is otherwise
black. Two implementations of a rule, not one implementation's gap.
Which this codebase already knew. `src/term/shm.rs` sweeps by presence *because* an object
that still exists is one the terminal has not read; the sentence that makes the sweep work
is the one that makes one object per frame impossible. It was in the tree the whole time,
two files from the change.
So no code moves here: the emission is an object per tile, byte for byte what it was. What
changes is what the tree says about why, in the three places that were guessing --
`place_shm`, the pty assertion, and the finding in RENDERING.md -- and the finding is closed
rather than left open. It now says what is not worth doing (probing for it, gating on a
terminal's name, trying a third terminal) and what would work: one *transmission* per frame,
packing the tiles into a single atlas, `a=t` once, then `a=p` per tile with a source
rectangle out of the stored image. That is one read, and legal. Its cost is written down
too, because it is not small -- image ids become per-frame rather than per-tile, which drags
in the `a=d,d=i` release, `TileGrid`'s id scheme, the cursor and overlay z-order, and
deletes for an image store that grows a frame at a time.
The numbers are re-measured on this machine rather than carried over, and the benchmark
keeps the one-object row so the 0.2 ms still on the table stays a number rather than a
memory:
shm: object per tile 1.6 ms/frame -> 633 fps ceiling
shm: per tile, packed in place 0.9 ms/frame -> 1124 fps ceiling
shm: one object per frame 0.7 ms/frame -> 1528 fps ceiling
Net of the two attempts: the larger half is in and unaffected -- packing into the mapping
the terminal reads rather than into a buffer to be copied in, 1.6 ms/frame to 0.9. The
offsets were the smaller half, and they were never available.
One thing this does not have: the error reply that would confirm the mechanism instead of
predicting it. `q=2` suppresses those, on both terminals. The finding says so, and says the
`q=0` reproduction is two lines of shell for whoever wants it certain.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
One object per frame, every tile placed out of it at an offset, was tried a second time -- against kitty this time, since the first attempt had only Ghostty's silence to go on. kitty draws it exactly as Ghostty does, which is to say it does not, and that is what identified the cause: the spec has the terminal "read the data from the memory object and then unlink and close it". One read is all an object gets. A frame that places ninety-one tiles out of one object makes ninety-one commands of it, the first consumes the name, and every later
shm_openfinds nothing -- so the frame's first tile draws and the screen is otherwise black. Two implementations of a rule, not one implementation's gap.Which this codebase already knew.
src/term/shm.rssweeps by presence because an object that still exists is one the terminal has not read; the sentence that makes the sweep work is the one that makes one object per frame impossible. It was in the tree the whole time, two files from the change.So no code moves here: the emission is an object per tile, byte for byte what it was. What changes is what the tree says about why, in the three places that were guessing --
place_shm, the pty assertion, and the finding in RENDERING.md -- and the finding is closed rather than left open. It now says what is not worth doing (probing for it, gating on a terminal's name, trying a third terminal) and what would work: one transmission per frame, packing the tiles into a single atlas,a=tonce, thena=pper tile with a source rectangle out of the stored image. That is one read, and legal. Its cost is written down too, because it is not small -- image ids become per-frame rather than per-tile, which drags in thea=d,d=irelease,TileGrid's id scheme, the cursor and overlay z-order, and deletes for an image store that grows a frame at a time.The numbers are re-measured on this machine rather than carried over, and the benchmark keeps the one-object row so the 0.2 ms still on the table stays a number rather than a memory:
Net of the two attempts: the larger half is in and unaffected -- packing into the mapping the terminal reads rather than into a buffer to be copied in, 1.6 ms/frame to 0.9. The offsets were the smaller half, and they were never available.
One thing this does not have: the error reply that would confirm the mechanism instead of predicting it.
q=2suppresses those, on both terminals. The finding says so, and says theq=0reproduction is two lines of shell for whoever wants it certain.