added debug

This commit is contained in:
nvrl committed 2026-11-01 21:13:55 +01:00
1 parent cef3ffd240
commit 1074ece0c6
4 files changed
+46 -5

No files matched your search

+19 -1
View File
@@ -65,6 +65,8 @@ export interface DropState {
}
export class LiquidBlob {
/// Why the last `create` gave up, for `?debug=drop`.
static failure = "";
readonly canvas = document.createElement("canvas");
/// Called if the GPU drops the context; the page shows plain art until `onRestored`.
onLost: (() => void) | null = null;
@@ -113,7 +115,8 @@ export class LiquidBlob {
try {
return new LiquidBlob(touch);
} catch (err) {
console.warn("liquid visuals off:", (err as Error).message);
LiquidBlob.failure = (err as Error).message;
console.warn("liquid visuals off:", LiquidBlob.failure);
return null;
}
}
@@ -391,6 +394,21 @@ export class LiquidBlob {
);
}
/// What `?debug=drop` shows: the GPU, and how far the drop got.
describe(): string {
const gl = this.gl;
const info = gl.getExtension("WEBGL_debug_renderer_info");
const gpu = info ? gl.getParameter(info.UNMASKED_RENDERER_WEBGL) : gl.getParameter(gl.RENDERER);
const hp = gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT);
return [
`gpu ${gpu}`,
`vertex highp ${hp ? hp.precision : "?"} bits`,
`ready ${this.ready} · lost ${gl.isContextLost()} · error ${gl.getError()}`,
`morph ${this.morph.toFixed(2)} · quality ${this.quality} · canvas ${this.canvas.width}x${this.canvas.height}`,
`in page ${this.canvas.isConnected} · css ${this.canvas.clientWidth}x${this.canvas.clientHeight}`,
].join("\n");
}
/// Stepped down to the lowest quality: the GPU had trouble keeping up.
get struggling(): boolean {
return this.quality === QUALITY.length - 1;
+16 -1
View File
@@ -1,5 +1,6 @@
// `?debug=audio`: live bars of what features.ts hears, for tuning its constants by
// ear. Loaded only when asked for.
// ear. `?debug=drop`: why the liquid drop does or does not show, readable on a
// phone without remote dev tools. Loaded only when asked for.
import type { Features } from "./features";
@@ -36,3 +37,17 @@ export function audioDebug(): (f: Features) => void {
});
};
}
/// A box of text, rewritten at most a few times a second.
export function dropDebug(): (text: string) => void {
const el = document.createElement("pre");
el.className = "audio-debug drop-debug";
document.body.append(el);
let at = 0;
return (text) => {
const now = performance.now();
if (now - at < 250) return;
at = now;
el.textContent = text;
};
}
+2
View File
@@ -482,6 +482,8 @@ button.danger:not(.link) { background: var(--accent); border: none; color: #fff;
pointer-events: none;
}
.drop-debug { margin: 0; padding: 0.4rem 0.5rem; max-width: calc(100vw - 1.4rem); font: 10px/1.35 ui-monospace, monospace; color: #fffc; white-space: pre-wrap; }
.card.paused .art { transform: scale(0.96); filter: brightness(0.7); }
.paused-badge {
position: absolute;
+9 -3
View File
@@ -68,6 +68,7 @@ export class Visualizer {
private reduced = matchMedia("(prefers-reduced-motion: reduce)");
private setting: VisualsSetting = localStorage.getItem(VISUALS_KEY) === "simple" ? "simple" : "liquid";
private debug: ((f: Features) => void) | null = null;
private dropDebug: ((text: string) => void) | null = null;
/// A press on the drop; `on` once it moved enough to turn it.
private grab: { id: number; x: number; y: number; on: boolean } | null = null;
private spun = false;
@@ -103,9 +104,9 @@ export class Visualizer {
if (this.spun) e.stopPropagation();
this.spun = false;
}, true);
if (new URLSearchParams(location.search).get("debug") === "audio") {
import("./debug").then((m) => { this.debug = m.audioDebug(); });
}
const debug = new URLSearchParams(location.search).get("debug");
if (debug === "audio") import("./debug").then((m) => { this.debug = m.audioDebug(); });
if (debug === "drop") import("./debug").then((m) => { this.dropDebug = m.dropDebug(); this.start(); });
}
get visuals(): VisualsSetting {
@@ -529,6 +530,11 @@ export class Visualizer {
? this.features.fromAnalyser(an, now / 1000, dt)
: this.features.fromLoudness(card.loudnessAt(progress), now / 1000, dt);
this.debug?.(f);
this.dropDebug?.([
`setting ${this.setting} · reduced motion ${this.reduced.matches} · touch ${this.touch} · mixing ${mixed}`,
`blob ${this.blob === undefined ? "not asked" : this.blob === null ? `failed: ${LiquidBlob.failure}` : "made"} · card liquid ${!!card.el?.classList.contains("liquid")}`,
this.blob?.describe() ?? "",
].join("\n"));
let busy = this.shine(now, dt, f.kick) || playing;
const liquid = !!this.blob && !!card.el?.classList.contains("liquid");
if (!this.reduced.matches) {