4
4
*--------------------------------------------------------------------------------------------*/
5
5
6
6
import type { IBuffer , IMarker , ITheme , Terminal as RawXtermTerminal } from 'xterm' ;
7
+ import type { CanvasAddon as CanvasAddonType } from 'xterm-addon-canvas' ;
7
8
import type { ISearchOptions , SearchAddon as SearchAddonType } from 'xterm-addon-search' ;
8
9
import type { Unicode11Addon as Unicode11AddonType } from 'xterm-addon-unicode11' ;
9
10
import type { WebglAddon as WebglAddonType } from 'xterm-addon-webgl' ;
10
- import { SerializeAddon as SerializeAddonType } from 'xterm-addon-serialize' ;
11
+ import type { SerializeAddon as SerializeAddonType } from 'xterm-addon-serialize' ;
11
12
import { IXtermCore } from 'vs/workbench/contrib/terminal/browser/xterm-private' ;
12
13
import { ConfigurationTarget , IConfigurationService } from 'vs/platform/configuration/common/configuration' ;
13
14
import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper' ;
@@ -42,10 +43,11 @@ import { IGenericMarkProperties } from 'vs/platform/terminal/common/terminalProc
42
43
const SLOW_CANVAS_RENDER_THRESHOLD = 50 ;
43
44
const NUMBER_OF_FRAMES_TO_MEASURE = 20 ;
44
45
46
+ let CanvasAddon : typeof CanvasAddonType ;
45
47
let SearchAddon : typeof SearchAddonType ;
48
+ let SerializeAddon : typeof SerializeAddonType ;
46
49
let Unicode11Addon : typeof Unicode11AddonType ;
47
50
let WebglAddon : typeof WebglAddonType ;
48
- let SerializeAddon : typeof SerializeAddonType ;
49
51
50
52
/**
51
53
* Wraps the xterm object with additional functionality. Interaction with the backing process is out
@@ -65,6 +67,7 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
65
67
private _decorationAddon : DecorationAddon ;
66
68
67
69
// Optional addons
70
+ private _canvasAddon ?: CanvasAddonType ;
68
71
private _searchAddon ?: SearchAddonType ;
69
72
private _unicode11Addon ?: Unicode11AddonType ;
70
73
private _webglAddon ?: WebglAddonType ;
@@ -140,7 +143,6 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
140
143
fastScrollModifier : 'alt' ,
141
144
fastScrollSensitivity : config . fastScrollSensitivity ,
142
145
scrollSensitivity : config . mouseWheelScrollSensitivity ,
143
- // rendererType: this._getBuiltInXtermRenderer(config.gpuAcceleration, XtermTerminal._suggestedRendererType),
144
146
wordSeparator : config . wordSeparators ,
145
147
overviewRulerWidth : 10
146
148
} ) ) ;
@@ -214,6 +216,9 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
214
216
this . _container = container ;
215
217
if ( this . _shouldLoadWebgl ( ) ) {
216
218
this . _enableWebglRenderer ( ) ;
219
+ } else if ( this . _shouldLoadCanvas ( ) ) {
220
+ this . _enableCanvasRenderer ( ) ;
221
+ // rendererType: this._getBuiltInXtermRenderer(config.gpuAcceleration, XtermTerminal._suggestedRendererType),
217
222
}
218
223
// Screen must be created at this point as xterm.open is called
219
224
return this . _container . querySelector ( '.xterm-screen' ) ! ;
@@ -241,15 +246,22 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
241
246
this . _enableWebglRenderer ( ) ;
242
247
} else {
243
248
this . _disposeOfWebglRenderer ( ) ;
244
- // TODO: Fix renderer
245
- // this.raw.options.rendererType = this._getBuiltInXtermRenderer(config.gpuAcceleration, XtermTerminal._suggestedRendererType);
249
+ if ( this . _shouldLoadCanvas ( ) ) {
250
+ this . _enableCanvasRenderer ( ) ;
251
+ } else {
252
+ this . _disposeOfCanvasRenderer ( ) ;
253
+ }
246
254
}
247
255
}
248
256
249
257
private _shouldLoadWebgl ( ) : boolean {
250
258
return ! isSafari && ( this . _configHelper . config . gpuAcceleration === 'auto' && XtermTerminal . _suggestedRendererType === undefined ) || this . _configHelper . config . gpuAcceleration === 'on' ;
251
259
}
252
260
261
+ private _shouldLoadCanvas ( ) : boolean {
262
+ return ( this . _configHelper . config . gpuAcceleration === 'auto' && ( XtermTerminal . _suggestedRendererType === undefined || XtermTerminal . _suggestedRendererType === 'canvas' ) ) || this . _configHelper . config . gpuAcceleration === 'canvas' ;
263
+ }
264
+
253
265
forceRedraw ( ) {
254
266
this . _webglAddon ?. clearTextureAtlas ( ) ;
255
267
this . raw . clearTextureAtlas ( ) ;
@@ -436,6 +448,7 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
436
448
}
437
449
const Addon = await this . _getWebglAddonConstructor ( ) ;
438
450
this . _webglAddon = new Addon ( ) ;
451
+ this . _disposeOfCanvasRenderer ( ) ;
439
452
try {
440
453
this . raw . loadAddon ( this . _webglAddon ) ;
441
454
this . _logService . trace ( 'Webgl was loaded' ) ;
@@ -458,13 +471,41 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
458
471
if ( ! neverMeasureRenderTime && this . _configHelper . config . gpuAcceleration !== 'off' ) {
459
472
this . _measureRenderTime ( ) ;
460
473
}
461
- // TODO: Fix renderer
462
- // this.raw.options.rendererType = 'canvas';
463
- // XtermTerminal._suggestedRendererType = 'canvas';
474
+ XtermTerminal . _suggestedRendererType = 'canvas' ;
464
475
this . _disposeOfWebglRenderer ( ) ;
476
+ this . _enableCanvasRenderer ( ) ;
465
477
}
466
478
}
467
479
480
+ private async _enableCanvasRenderer ( ) : Promise < void > {
481
+ if ( ! this . raw . element || this . _canvasAddon ) {
482
+ return ;
483
+ }
484
+ const Addon = await this . _getCanvasAddonConstructor ( ) ;
485
+ this . _canvasAddon = new Addon ( ) ;
486
+ this . _disposeOfWebglRenderer ( ) ;
487
+ try {
488
+ this . raw . loadAddon ( this . _canvasAddon ) ;
489
+ this . _logService . trace ( 'Canvas was loaded' ) ;
490
+ } catch ( e ) {
491
+ this . _logService . warn ( `Canvas could not be loaded. Falling back to the dom renderer type.` , e ) ;
492
+ const neverMeasureRenderTime = this . _storageService . getBoolean ( TerminalStorageKeys . NeverMeasureRenderTime , StorageScope . APPLICATION , false ) ;
493
+ // if it's already set to dom, no need to measure render time
494
+ if ( ! neverMeasureRenderTime && this . _configHelper . config . gpuAcceleration !== 'off' ) {
495
+ this . _measureRenderTime ( ) ;
496
+ }
497
+ XtermTerminal . _suggestedRendererType = 'dom' ;
498
+ this . _disposeOfCanvasRenderer ( ) ;
499
+ }
500
+ }
501
+
502
+ protected async _getCanvasAddonConstructor ( ) : Promise < typeof CanvasAddonType > {
503
+ if ( ! CanvasAddon ) {
504
+ CanvasAddon = ( await import ( 'xterm-addon-canvas' ) ) . CanvasAddon ;
505
+ }
506
+ return CanvasAddon ;
507
+ }
508
+
468
509
protected async _getSearchAddonConstructor ( ) : Promise < typeof SearchAddonType > {
469
510
if ( ! SearchAddon ) {
470
511
SearchAddon = ( await import ( 'xterm-addon-search' ) ) . SearchAddon ;
@@ -493,6 +534,15 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
493
534
return SerializeAddon ;
494
535
}
495
536
537
+ private _disposeOfCanvasRenderer ( ) : void {
538
+ try {
539
+ this . _canvasAddon ?. dispose ( ) ;
540
+ } catch {
541
+ // ignore
542
+ }
543
+ this . _canvasAddon = undefined ;
544
+ }
545
+
496
546
private _disposeOfWebglRenderer ( ) : void {
497
547
try {
498
548
this . _webglAddon ?. dispose ( ) ;
0 commit comments