Render through a desynchronized WebGL context by default
Measured click-to-paint was 72-77 ms, of which the editor itself spends under 4 ms; the rest is the finished frame waiting in the compositor queue. A desynchronized context bypasses it (16-18 ms in the same probe). Pixi has no option for it, so main.ts builds the WebGL2 context itself. The mode may tear on some drivers; ?vsync falls back to Pixi's own context. __gm.lowLatency() reports the attributes the browser actually granted, and a graph-step check pins that the mode stays on. Also adds the todo note graph-node-collapse-width. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
13852fe4b2
commit
0dcb3b4432
5 files changed
+30
-2
No files matched your search
@@ -281,6 +281,9 @@ export function installDebugHook(app: Application, state: EditorState, editor: E
|
||||
};
|
||||
},
|
||||
fps: () => editor.fps,
|
||||
lowLatency: () =>
|
||||
(app.renderer as unknown as { gl?: WebGL2RenderingContext }).gl?.getContextAttributes()
|
||||
?.desynchronized === true,
|
||||
tab: () => editor.tab,
|
||||
showTab: (tab: CentreTab) => editor.showTab(tab),
|
||||
};
|
||||
|
||||
+16
-1
@@ -6,7 +6,22 @@ import { startEditor } from './editor/App';
|
||||
import { mountPlayground } from './playground';
|
||||
import { initUI, Theme, VStack } from './ui';
|
||||
|
||||
// `desynchronized` bypasses the compositor queue (headless click-to-paint 72 → 16 ms) but may
|
||||
// tear; `?vsync` opts out. Pixi has no option for it, hence our own context.
|
||||
function lowLatencyContext(): { canvas?: HTMLCanvasElement; context?: WebGL2RenderingContext } {
|
||||
const canvas = document.createElement('canvas');
|
||||
const context = canvas.getContext('webgl2', {
|
||||
alpha: false,
|
||||
antialias: true,
|
||||
premultipliedAlpha: true,
|
||||
stencil: true,
|
||||
desynchronized: true,
|
||||
});
|
||||
return context ? { canvas, context } : {};
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
const params = new URLSearchParams(location.search);
|
||||
const app = new Application();
|
||||
await app.init({
|
||||
resizeTo: window,
|
||||
@@ -15,6 +30,7 @@ async function main(): Promise<void> {
|
||||
resolution: Math.min(2, window.devicePixelRatio || 1),
|
||||
autoDensity: true,
|
||||
preference: 'webgl',
|
||||
...(params.has('vsync') ? {} : lowLatencyContext()),
|
||||
});
|
||||
document.body.appendChild(app.canvas);
|
||||
|
||||
@@ -25,7 +41,6 @@ async function main(): Promise<void> {
|
||||
app.stage.hitArea = app.screen;
|
||||
initUI(app, root, overlay);
|
||||
|
||||
const params = new URLSearchParams(location.search);
|
||||
if (params.has('playground')) mountPlayground(app, root);
|
||||
else await startEditor(app, root);
|
||||
|
||||
|
||||
Reference in new issue
Block a user