Skip to content

Commit 7e4c781

Browse files
committed
webgl status icon/toggle for debugging
1 parent 134b388 commit 7e4c781

6 files changed

Lines changed: 104 additions & 13 deletions

File tree

frontend/app/view/term/term-model.ts

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import * as jotai from "jotai";
4141
import * as React from "react";
4242
import { getBlockingCommand } from "./shellblocking";
4343
import { computeTheme, DefaultTermTheme } from "./termutil";
44-
import { TermWrap } from "./termwrap";
44+
import { TermWrap, WebGLSupported } from "./termwrap";
4545

4646
export class TermViewModel implements ViewModel {
4747
viewType: string;
@@ -293,6 +293,13 @@ export class TermViewModel implements ViewModel {
293293
}
294294
}
295295

296+
if (get(getSettingsKeyAtom("debug:webglstatus"))) {
297+
const webglButton = this.getWebGlIconButton(get);
298+
if (webglButton) {
299+
rtn.push(webglButton);
300+
}
301+
}
302+
296303
if (blockData?.meta?.["controller"] != "cmd" && shellProcStatus != "done") {
297304
return rtn;
298305
}
@@ -438,6 +445,38 @@ export class TermViewModel implements ViewModel {
438445
return null;
439446
}
440447

448+
getWebGlIconButton(get: jotai.Getter): IconButtonDecl | null {
449+
if (!WebGLSupported) {
450+
return {
451+
elemtype: "iconbutton",
452+
icon: "microchip",
453+
iconColor: "var(--error-color)",
454+
title: "WebGL not supported",
455+
noAction: true,
456+
};
457+
}
458+
if (!this.termRef.current?.webglEnabledAtom) {
459+
return null;
460+
}
461+
const webglEnabled = get(this.termRef.current.webglEnabledAtom);
462+
if (webglEnabled) {
463+
return {
464+
elemtype: "iconbutton",
465+
icon: "microchip",
466+
iconColor: "var(--success-color)",
467+
title: "WebGL enabled (click to disable)",
468+
click: () => this.toggleWebGl(),
469+
};
470+
}
471+
return {
472+
elemtype: "iconbutton",
473+
icon: "microchip",
474+
iconColor: "var(--secondary-text-color)",
475+
title: "WebGL disabled (click to enable)",
476+
click: () => this.toggleWebGl(),
477+
};
478+
}
479+
441480
get viewComponent(): ViewComponent {
442481
return TerminalView as ViewComponent;
443482
}
@@ -478,6 +517,21 @@ export class TermViewModel implements ViewModel {
478517
});
479518
}
480519

520+
isWebGlEnabled(): boolean {
521+
return this.termRef.current?.isWebGlEnabled() ?? false;
522+
}
523+
524+
toggleWebGl() {
525+
if (!this.termRef.current) {
526+
return;
527+
}
528+
if (this.termRef.current.isWebGlEnabled()) {
529+
this.termRef.current.disableWebGl();
530+
} else {
531+
this.termRef.current.enableWebGl();
532+
}
533+
}
534+
481535
triggerRestartAtom() {
482536
globalStore.set(this.isRestarting, true);
483537
setTimeout(() => {

frontend/app/view/term/termwrap.ts

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ function detectWebGLSupport(): boolean {
5656
}
5757
}
5858

59-
const WebGLSupported = detectWebGLSupport();
59+
export const WebGLSupported = detectWebGLSupport();
6060
let loggedWebGL = false;
6161

6262
type TermWrapOptions = {
@@ -85,6 +85,8 @@ export class TermWrap {
8585
sendDataHandler: (data: string) => void;
8686
onSearchResultsDidChange?: (result: { resultIndex: number; resultCount: number }) => void;
8787
private toDispose: TermTypes.IDisposable[] = [];
88+
webglAddon: WebglAddon | null = null;
89+
webglEnabledAtom: jotai.PrimitiveAtom<boolean>;
8890
pasteActive: boolean = false;
8991
lastUpdated: number;
9092
promptMarkers: TermTypes.IMarker[] = [];
@@ -142,6 +144,7 @@ export class TermWrap {
142144
this.promptMarkers = [];
143145
this.shellIntegrationStatusAtom = jotai.atom(null) as jotai.PrimitiveAtom<ShellIntegrationStatus | null>;
144146
this.lastCommandAtom = jotai.atom(null) as jotai.PrimitiveAtom<string | null>;
147+
this.webglEnabledAtom = jotai.atom(false) as jotai.PrimitiveAtom<boolean>;
145148
this.terminal = new Terminal(options);
146149
this.fitAddon = new FitAddon();
147150
this.fitAddon.scrollbarWidth = 6; // this needs to match scrollbar width in term.scss
@@ -180,17 +183,7 @@ export class TermWrap {
180183
)
181184
);
182185
if (WebGLSupported && waveOptions.useWebGl) {
183-
const webglAddon = new WebglAddon();
184-
this.toDispose.push(
185-
webglAddon.onContextLoss(() => {
186-
webglAddon.dispose();
187-
})
188-
);
189-
this.terminal.loadAddon(webglAddon);
190-
if (!loggedWebGL) {
191-
console.log("loaded webgl!");
192-
loggedWebGL = true;
193-
}
186+
this.loadWebGlAddon();
194187
}
195188
// Register OSC handlers
196189
this.terminal.parser.registerOscHandler(7, (data: string) => {
@@ -307,6 +300,44 @@ export class TermWrap {
307300
this.terminal.options.cursorBlink = cursorBlink ?? false;
308301
}
309302

303+
loadWebGlAddon() {
304+
const addon = new WebglAddon();
305+
this.toDispose.push(
306+
addon.onContextLoss(() => {
307+
if (addon === this.webglAddon) {
308+
this.disableWebGl();
309+
}
310+
})
311+
);
312+
this.terminal.loadAddon(addon);
313+
this.webglAddon = addon;
314+
globalStore.set(this.webglEnabledAtom, true);
315+
if (!loggedWebGL) {
316+
console.log("loaded webgl!");
317+
loggedWebGL = true;
318+
}
319+
}
320+
321+
isWebGlEnabled(): boolean {
322+
return this.webglAddon != null;
323+
}
324+
325+
enableWebGl() {
326+
if (!WebGLSupported || this.webglAddon != null) {
327+
return;
328+
}
329+
this.loadWebGlAddon();
330+
}
331+
332+
disableWebGl() {
333+
if (this.webglAddon == null) {
334+
return;
335+
}
336+
this.webglAddon.dispose();
337+
this.webglAddon = null;
338+
globalStore.set(this.webglEnabledAtom, false);
339+
}
340+
310341
resetCompositionState() {
311342
this.isComposing = false;
312343
this.composingData = "";

frontend/types/gotypes.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,6 +1395,7 @@ declare global {
13951395
"debug:*"?: boolean;
13961396
"debug:pprofport"?: number;
13971397
"debug:pprofmemprofilerate"?: number;
1398+
"debug:webglstatus"?: boolean;
13981399
"tsunami:*"?: boolean;
13991400
"tsunami:scaffoldpath"?: string;
14001401
"tsunami:sdkreplacepath"?: string;

pkg/wconfig/metaconsts.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ const (
121121
ConfigKey_DebugClear = "debug:*"
122122
ConfigKey_DebugPprofPort = "debug:pprofport"
123123
ConfigKey_DebugPprofMemProfileRate = "debug:pprofmemprofilerate"
124+
ConfigKey_DebugWebGlStatus = "debug:webglstatus"
124125

125126
ConfigKey_TsunamiClear = "tsunami:*"
126127
ConfigKey_TsunamiScaffoldPath = "tsunami:scaffoldpath"

pkg/wconfig/settingsconfig.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ type SettingsType struct {
172172
DebugClear bool `json:"debug:*,omitempty"`
173173
DebugPprofPort *int `json:"debug:pprofport,omitempty"`
174174
DebugPprofMemProfileRate *int `json:"debug:pprofmemprofilerate,omitempty"`
175+
DebugWebGlStatus bool `json:"debug:webglstatus,omitempty"`
175176

176177
TsunamiClear bool `json:"tsunami:*,omitempty"`
177178
TsunamiScaffoldPath string `json:"tsunami:scaffoldpath,omitempty"`

schema/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,9 @@
325325
"debug:pprofmemprofilerate": {
326326
"type": "integer"
327327
},
328+
"debug:webglstatus": {
329+
"type": "boolean"
330+
},
328331
"tsunami:*": {
329332
"type": "boolean"
330333
},

0 commit comments

Comments
 (0)