split snapshot profiler bucket into update vs marshal

The snapshot bucket lumped ghostty's native dirty-state update together with
the Java-side cell marshaling. Time them separately to see which half of the
~7ms/frame snapshot cost (now the dominant frame cost after the detectShift
hoist) is the real target.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Gregor Lohaus
2026-05-31 21:18:07 +02:00
parent 4923ea5527
commit e99a6ee33e
2 changed files with 13 additions and 2 deletions

View File

@@ -18,8 +18,11 @@ final class RenderProfiler {
static final int FINGERPRINT = 1; static final int FINGERPRINT = 1;
static final int DRAW = 2; static final int DRAW = 2;
static final int FRAME = 3; static final int FRAME = 3;
private static final int BUCKETS = 4; static final int UPDATE = 4;
private static final String[] NAMES = {"snapshot", "fingerprint", "draw", "frame-total"}; static final int MARSHAL = 5;
private static final int BUCKETS = 6;
private static final String[] NAMES =
{"snapshot", "fingerprint", "draw", "frame-total", "update", "marshal"};
private static final boolean ENABLED = private static final boolean ENABLED =
Boolean.getBoolean("jprototerm.profile") || "1".equals(System.getenv("JPROTOTERM_PROFILE")); Boolean.getBoolean("jprototerm.profile") || "1".equals(System.getenv("JPROTOTERM_PROFILE"));

View File

@@ -160,13 +160,21 @@ public final class TerminalPane implements AutoCloseable {
synchronized (terminal) { synchronized (terminal) {
long version = contentVersion.get(); long version = contentVersion.get();
if (full) { if (full) {
long updateStart = RenderProfiler.start();
renderState.update(terminal); renderState.update(terminal);
RenderProfiler.stop(RenderProfiler.UPDATE, updateStart);
long marshalStart = RenderProfiler.start();
cachedSnapshot = renderState.snapshot(); cachedSnapshot = renderState.snapshot();
RenderProfiler.stop(RenderProfiler.MARSHAL, marshalStart);
renderState.resetDirty(); renderState.resetDirty();
snapshotVersion = version; snapshotVersion = version;
} else if (snapshotVersion != version) { } else if (snapshotVersion != version) {
long updateStart = RenderProfiler.start();
renderState.update(terminal); renderState.update(terminal);
RenderProfiler.stop(RenderProfiler.UPDATE, updateStart);
long marshalStart = RenderProfiler.start();
cachedSnapshot = renderState.snapshotIncremental(); cachedSnapshot = renderState.snapshotIncremental();
RenderProfiler.stop(RenderProfiler.MARSHAL, marshalStart);
renderState.resetDirty(); renderState.resetDirty();
snapshotVersion = version; snapshotVersion = version;
} }