try to fix graphics path

This commit is contained in:
2026-06-01 02:18:01 +02:00
parent ebf87c0bff
commit 5f0edcbe31
3 changed files with 34 additions and 26 deletions

4
.ignore Normal file
View File

@@ -0,0 +1,4 @@
.gradle
bin
result
.worktrees

8
flake.lock generated
View File

@@ -70,11 +70,11 @@
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1780258814,
"narHash": "sha256-8rxL7xaZ/loYg3zdt0w5+hfNyHFVknDZN360NzrtCsQ=",
"lastModified": 1780272954,
"narHash": "sha256-bVWY60iw8yPIu7I8FuRPf06T0H1TDvQDVUlzeHQs8UA=",
"ref": "refs/heads/main",
"rev": "6a3d5aa0b0b1f738c958e2a2f0249574c07d9c4d",
"revCount": 23,
"rev": "06a9d5d3ecf11c58f0e41214d1b59900e672dd3a",
"revCount": 24,
"type": "git",
"url": "https://gitea.gregorlohaus.com/gregor/jlibghostty.git"
},

View File

@@ -1,8 +1,8 @@
package com.gregor.jprototerm;
import dev.jlibghostty.KittyImage;
import dev.jlibghostty.KittyImageCompression;
import dev.jlibghostty.KittyImageFormat;
import dev.jlibghostty.KittyImageSnapshot;
import dev.jlibghostty.KittyPlacement;
import dev.jlibghostty.KittyPlacementLayer;
import dev.jlibghostty.KittyPlaceholder;
@@ -461,7 +461,7 @@ final class GhosttyTerminalRenderer extends TerminalRenderer {
private static boolean hasKittyGraphics(RenderTarget target) {
return target.kittyGraphics()
.map(graphics -> !graphics.placements().isEmpty())
.map(graphics -> !graphics.isEmpty())
.orElse(false);
}
@@ -601,16 +601,17 @@ final class GhosttyTerminalRenderer extends TerminalRenderer {
}
private Image imageFor(KittyPlacement placement) {
return placement.image().map(snapshot -> {
byte[] data = snapshot.data();
KittyImageKey key = KittyImageKey.of(snapshot, data);
return placement.image().map(image -> {
// Build the cache key from cheap metadata only — the pixel buffer is never copied out
// of native memory on a cache hit (the common per-frame case).
KittyImageKey key = KittyImageKey.of(image);
Image cached = kittyImageCache.get(key);
if (cached != null) {
return cached;
}
kittyImageCache.keySet().removeIf(existing -> existing.id() == snapshot.id());
Image decoded = decodeImage(snapshot, data);
kittyImageCache.keySet().removeIf(existing -> existing.id() == image.id());
Image decoded = decodeImage(image);
if (decoded != null) {
kittyImageCache.put(key, decoded);
}
@@ -618,22 +619,25 @@ final class GhosttyTerminalRenderer extends TerminalRenderer {
}).orElse(null);
}
private Image decodeImage(KittyImageSnapshot snapshot, byte[] data) {
if (snapshot.compression() != KittyImageCompression.NONE) {
private Image decodeImage(KittyImage source) {
if (source.compression() != KittyImageCompression.NONE) {
return null;
}
if (snapshot.format() == KittyImageFormat.PNG) {
// Only now — on a cache miss — do we pull the raw bytes across the native boundary.
byte[] data = source.data();
KittyImageFormat format = source.format();
if (format == KittyImageFormat.PNG) {
return new Image(new ByteArrayInputStream(data));
}
int width = Math.toIntExact(snapshot.width());
int height = Math.toIntExact(snapshot.height());
int width = Math.toIntExact(source.width());
int height = Math.toIntExact(source.height());
WritableImage image = new WritableImage(width, height);
if (snapshot.format() == KittyImageFormat.RGBA) {
if (format == KittyImageFormat.RGBA) {
image.getPixelWriter().setPixels(0, 0, width, height, PixelFormat.getByteBgraInstance(), rgbaToBgra(data), 0, width * 4);
} else if (snapshot.format() == KittyImageFormat.RGB) {
} else if (format == KittyImageFormat.RGB) {
image.getPixelWriter().setPixels(0, 0, width, height, PixelFormat.getByteRgbInstance(), data, 0, width * 3);
}
return image;
@@ -1321,15 +1325,15 @@ final class GhosttyTerminalRenderer extends TerminalRenderer {
// identity + dimensions + payload length are enough to key the decoded-image cache, and
// we avoid fingerprinting the whole payload — which previously ran once per frame per
// placement (O(image size)) just to look the image up.
private record KittyImageKey(long id, long number, long width, long height, KittyImageFormat format, int dataLength) {
private static KittyImageKey of(KittyImageSnapshot snapshot, byte[] data) {
private record KittyImageKey(long id, long number, long width, long height, KittyImageFormat format, long dataLength) {
private static KittyImageKey of(KittyImage image) {
return new KittyImageKey(
snapshot.id(),
snapshot.number(),
snapshot.width(),
snapshot.height(),
snapshot.format(),
data.length
image.id(),
image.number(),
image.width(),
image.height(),
image.format(),
image.dataLength()
);
}
}