mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-07-12 04:09:40 +00:00
kitty/gfx: add generation stamps, delete transmit time
Add a generation counter to the kitty graphics image storage. Every
content mutation (image transmit/replace, placement add, delete)
assigns the storage a fresh stamp, and every image is stamped when
it is added or replaced.
This solves two problems:
First, a retransmission of the same image ID with identical dimensions
was previously undetectable by anything comparing width, height, format,
and data length; the per-image stamp changes on every add/replace, so caches
keyed on it always see the change. Second, the dirty flag was the only
storage-wide signal, and it is also set by scrolling and resizing, which move
placements without changing contents. The generation is only bumped by content
mutations, so an unchanged value means the placement set and all
image data are identical and consumers can skip re-reading them,
recomputing only placement geometry.
The generation replaces Image.transmit_time entirely: newest-image
lookup by number, eviction ordering, and the renderer's texture
staleness checks all key on it now. A monotonic counter strictly
orders transmissions where Instant-based times could collide within
clock resolution (the renderer previously assumed equal timestamps
meant identical images), and this removes a syscall and an error
path per transmission.
Delete commands now only mark a mutation (dirty flag and
generation) when they actually remove something. A delete-all runs
on every screen clear, so previously every ESC [ 2 J dirtied the
image state even with no images stored. Eviction via setLimit also
now marks the state dirty, which it previously did not.
Both generations are exposed through libghostty-vt as
GHOSTTY_KITTY_GRAPHICS_DATA_GENERATION and
GHOSTTY_KITTY_IMAGE_DATA_GENERATION (uint64_t), and the headers now
document that stored image data is always post-inflate/post-decode:
COMPRESSION always reports NONE, FORMAT is never PNG, and DATA_PTR
is raw pixels ready for GPU upload.
uint64_t gen = 0;
ghostty_kitty_graphics_get(
graphics, GHOSTTY_KITTY_GRAPHICS_DATA_GENERATION, &gen);
if (gen == last_gen) return; // nothing changed, skip re-reads
This commit is contained in:
@@ -125,6 +125,17 @@ int main() {
|
||||
}
|
||||
printf("\nKitty graphics storage is available.\n");
|
||||
|
||||
/*
|
||||
* The storage-wide generation changes on every image/placement
|
||||
* mutation. Renderers can compare it against the value from the
|
||||
* previous frame: if unchanged, placement iteration and image
|
||||
* staleness checks can be skipped entirely.
|
||||
*/
|
||||
uint64_t generation = 0;
|
||||
ghostty_kitty_graphics_get(graphics, GHOSTTY_KITTY_GRAPHICS_DATA_GENERATION,
|
||||
&generation);
|
||||
printf("Storage generation: %llu\n", (unsigned long long)generation);
|
||||
|
||||
/* Iterate placements to find the image ID. */
|
||||
GhosttyKittyGraphicsPlacementIterator iter = NULL;
|
||||
if (ghostty_kitty_graphics_placement_iterator_new(NULL, &iter) != GHOSTTY_SUCCESS) {
|
||||
@@ -170,20 +181,30 @@ int main() {
|
||||
uint32_t width = 0, height = 0, number = 0;
|
||||
GhosttyKittyImageFormat format = 0;
|
||||
size_t data_len = 0;
|
||||
uint64_t image_generation = 0;
|
||||
|
||||
ghostty_kitty_graphics_image_get_multi(image, 5,
|
||||
/*
|
||||
* The per-image generation changes on every add/replace of this
|
||||
* image ID, so it detects retransmissions even when the size and
|
||||
* format are unchanged. Texture caches should key staleness on it.
|
||||
*/
|
||||
ghostty_kitty_graphics_image_get_multi(image, 6,
|
||||
(GhosttyKittyGraphicsImageData[]){
|
||||
GHOSTTY_KITTY_IMAGE_DATA_NUMBER,
|
||||
GHOSTTY_KITTY_IMAGE_DATA_WIDTH,
|
||||
GHOSTTY_KITTY_IMAGE_DATA_HEIGHT,
|
||||
GHOSTTY_KITTY_IMAGE_DATA_FORMAT,
|
||||
GHOSTTY_KITTY_IMAGE_DATA_DATA_LEN,
|
||||
GHOSTTY_KITTY_IMAGE_DATA_GENERATION,
|
||||
},
|
||||
(void*[]){ &number, &width, &height, &format, &data_len },
|
||||
(void*[]){ &number, &width, &height, &format, &data_len,
|
||||
&image_generation },
|
||||
NULL);
|
||||
|
||||
printf(" image: number=%u size=%ux%u format=%d data_len=%zu\n",
|
||||
number, width, height, format, data_len);
|
||||
printf(" image: number=%u size=%ux%u format=%d data_len=%zu "
|
||||
"generation=%llu\n",
|
||||
number, width, height, format, data_len,
|
||||
(unsigned long long)image_generation);
|
||||
|
||||
/* Compute the rendered pixel size and grid size. */
|
||||
uint32_t px_w = 0, px_h = 0, cols = 0, rows = 0;
|
||||
|
||||
Reference in New Issue
Block a user