Merge pull request #209277 from microsoft/tyriar/209275

Remove xterm canvas renderer from fallback logic
This commit is contained in:
Daniel Imms 2024-04-01 10:42:55 -07:00 committed by GitHub
commit 8bdc74cd9e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 10 additions and 83 deletions

View file

@ -40,9 +40,7 @@ export interface IXtermCore {
}
},
_renderer: {
value?: {
_renderLayers?: any[];
}
value?: unknown;
};
_handleIntersectionChange: any;
};

View file

@ -12,7 +12,7 @@ import type { SerializeAddon as SerializeAddonType } from '@xterm/addon-serializ
import type { ImageAddon as ImageAddonType } from '@xterm/addon-image';
import * as dom from 'vs/base/browser/dom';
import { IXtermCore } from 'vs/workbench/contrib/terminal/browser/xterm-private';
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper';
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
@ -21,9 +21,7 @@ import { ITerminalFont, ITerminalConfiguration } from 'vs/workbench/contrib/term
import { isSafari } from 'vs/base/browser/browser';
import { IMarkTracker, IInternalXtermTerminal, IXtermTerminal, IXtermColorProvider, XtermTerminalConstants, IXtermAttachToElementOptions, IDetachedXtermTerminal, ITerminalConfigurationService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { LogLevel } from 'vs/platform/log/common/log';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { TerminalStorageKeys } from 'vs/workbench/contrib/terminal/common/terminalStorageKeys';
import { INotificationService, IPromptChoice, Severity } from 'vs/platform/notification/common/notification';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { MarkNavigationAddon, ScrollPosition } from 'vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon';
import { localize } from 'vs/nls';
import { IColorTheme, IThemeService } from 'vs/platform/theme/common/themeService';
@ -46,12 +44,6 @@ import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
import { AccessibilitySignal, IAccessibilitySignalService } from 'vs/platform/accessibilitySignal/browser/accessibilitySignalService';
const enum RenderConstants {
/**
* How long in milliseconds should an average frame take to render for a notification to appear
* which suggests the fallback DOM-based renderer.
*/
SlowCanvasRenderThreshold = 50,
NumberOfFramestoMeasure = 20,
SmoothScrollDuration = 125
}
@ -120,7 +112,7 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach
/** The raw xterm.js instance */
readonly raw: RawXtermTerminal;
private _core: IXtermCore;
private static _suggestedRendererType: 'canvas' | 'dom' | undefined = undefined;
private static _suggestedRendererType: 'dom' | undefined = undefined;
private static _checkedWebglCompatible = false;
private _attached?: { container: HTMLElement; options: IXtermAttachToElementOptions };
private _isPhysicalMouseWheel = MouseWheelClassifier.INSTANCE.isPhysicalMouseWheel();
@ -200,7 +192,6 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach
@IInstantiationService private readonly _instantiationService: IInstantiationService,
@ITerminalLogService private readonly _logService: ITerminalLogService,
@INotificationService private readonly _notificationService: INotificationService,
@IStorageService private readonly _storageService: IStorageService,
@IThemeService private readonly _themeService: IThemeService,
@ITelemetryService private readonly _telemetryService: ITelemetryService,
@ITerminalConfigurationService private readonly _terminalConfigurationService: ITerminalConfigurationService,
@ -431,7 +422,7 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach
}
private _shouldLoadCanvas(): boolean {
return (this._terminalConfigurationService.config.gpuAcceleration === 'auto' && (XtermTerminal._suggestedRendererType === undefined || XtermTerminal._suggestedRendererType === 'canvas')) || this._terminalConfigurationService.config.gpuAcceleration === 'canvas';
return this._terminalConfigurationService.config.gpuAcceleration === 'canvas';
}
forceRedraw() {
@ -716,22 +707,19 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach
// }
// }, 5000);
} catch (e) {
this._logService.warn(`Webgl could not be loaded. Falling back to the canvas renderer type.`, e);
const neverMeasureRenderTime = this._storageService.getBoolean(TerminalStorageKeys.NeverMeasureRenderTime, StorageScope.APPLICATION, false);
// if it's already set to dom, no need to measure render time
if (!neverMeasureRenderTime && this._terminalConfigurationService.config.gpuAcceleration !== 'off') {
this._measureRenderTime();
}
this._logService.warn(`Webgl could not be loaded. Falling back to the DOM renderer`, e);
this._disableWebglForThisSession();
}
}
private _disableWebglForThisSession() {
XtermTerminal._suggestedRendererType = 'canvas';
XtermTerminal._suggestedRendererType = 'dom';
this._disposeOfWebglRenderer();
this._enableCanvasRenderer();
}
/**
* @deprecated This will be removed in the future, see https://github.com/microsoft/vscode/issues/209276
*/
private async _enableCanvasRenderer(): Promise<void> {
if (!this.raw.element || this._canvasAddon) {
return;
@ -744,11 +732,6 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach
this._logService.trace('Canvas renderer was loaded');
} catch (e) {
this._logService.warn(`Canvas renderer could not be loaded, falling back to dom renderer`, e);
const neverMeasureRenderTime = this._storageService.getBoolean(TerminalStorageKeys.NeverMeasureRenderTime, StorageScope.APPLICATION, false);
// if it's already set to dom, no need to measure render time
if (!neverMeasureRenderTime && this._terminalConfigurationService.config.gpuAcceleration !== 'off') {
this._measureRenderTime();
}
XtermTerminal._suggestedRendererType = 'dom';
this._disposeOfCanvasRenderer();
}
@ -836,59 +819,6 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach
this._refreshImageAddon();
}
private async _measureRenderTime(): Promise<void> {
const frameTimes: number[] = [];
if (!this._core._renderService?._renderer.value?._renderLayers) {
return;
}
const textRenderLayer = this._core._renderService._renderer.value._renderLayers[0];
const originalOnGridChanged = textRenderLayer?.onGridChanged;
const evaluateCanvasRenderer = () => {
// Discard first frame time as it's normal to take longer
frameTimes.shift();
const medianTime = frameTimes.sort((a, b) => a - b)[Math.floor(frameTimes.length / 2)];
if (medianTime > RenderConstants.SlowCanvasRenderThreshold) {
if (this._terminalConfigurationService.config.gpuAcceleration === 'auto') {
XtermTerminal._suggestedRendererType = 'dom';
this.updateConfig();
} else {
const promptChoices: IPromptChoice[] = [
{
label: localize('yes', "Yes"),
run: () => this._configurationService.updateValue(TerminalSettingId.GpuAcceleration, 'off', ConfigurationTarget.USER)
} as IPromptChoice,
{
label: localize('no', "No"),
run: () => { }
} as IPromptChoice,
{
label: localize('dontShowAgain', "Don't Show Again"),
isSecondary: true,
run: () => this._storageService.store(TerminalStorageKeys.NeverMeasureRenderTime, true, StorageScope.APPLICATION, StorageTarget.MACHINE)
} as IPromptChoice
];
this._notificationService.prompt(
Severity.Warning,
localize('terminal.slowRendering', 'Terminal GPU acceleration appears to be slow on your computer. Would you like to switch to disable it which may improve performance? [Read more about terminal settings](https://code.visualstudio.com/docs/editor/integrated-terminal#_changing-how-the-terminal-is-rendered).'),
promptChoices
);
}
}
};
textRenderLayer.onGridChanged = (terminal: RawXtermTerminal, firstRow: number, lastRow: number) => {
const startTime = performance.now();
originalOnGridChanged.call(textRenderLayer, terminal, firstRow, lastRow);
frameTimes.push(performance.now() - startTime);
if (frameTimes.length === RenderConstants.NumberOfFramestoMeasure) {
evaluateCanvasRenderer();
// Restore original function
textRenderLayer.onGridChanged = originalOnGridChanged;
}
};
}
getXtermTheme(theme?: IColorTheme): ITheme {
if (!theme) {
theme = this._themeService.getColorTheme();

View file

@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
export const enum TerminalStorageKeys {
NeverMeasureRenderTime = 'terminal.integrated.neverMeasureRenderTime',
SuggestedRendererType = 'terminal.integrated.suggestedRendererType',
TabsListWidthHorizontal = 'tabs-list-width-horizontal',
TabsListWidthVertical = 'tabs-list-width-vertical',