From 84eb4778f18215d00608ccf8fb7649e6f2cd428a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 17 May 2018 10:18:41 -0700 Subject: [PATCH] Show notification for DOM renderer Part of #46954 --- .../parts/terminal/common/terminal.ts | 1 + .../electron-browser/terminalInstance.ts | 59 +++++++++++++++++-- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/parts/terminal/common/terminal.ts b/src/vs/workbench/parts/terminal/common/terminal.ts index ccff25889b4..ff748df861b 100644 --- a/src/vs/workbench/parts/terminal/common/terminal.ts +++ b/src/vs/workbench/parts/terminal/common/terminal.ts @@ -34,6 +34,7 @@ export const KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_INPUT_NOT_FOCUSED: ContextK export const IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY = 'terminal.integrated.isWorkspaceShellAllowed'; export const NEVER_SUGGEST_SELECT_WINDOWS_SHELL_STORAGE_KEY = 'terminal.integrated.neverSuggestSelectWindowsShell'; +export const NEVER_MEASURE_RENDER_TIME_STORAGE_KEY = 'terminal.integrated.neverMeasureRenderTime'; export const ITerminalService = createDecorator(TERMINAL_SERVICE_ID); diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts index fbdf76a1b89..4590dd5ebd7 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts @@ -14,7 +14,7 @@ import { Terminal as XTermTerminal } from 'vscode-xterm'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; -import { ITerminalInstance, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, TERMINAL_PANEL_ID, IShellLaunchConfig, ITerminalProcessManager, ProcessState } from 'vs/workbench/parts/terminal/common/terminal'; +import { ITerminalInstance, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, TERMINAL_PANEL_ID, IShellLaunchConfig, ITerminalProcessManager, ProcessState, NEVER_MEASURE_RENDER_TIME_STORAGE_KEY } from 'vs/workbench/parts/terminal/common/terminal'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { TabFocus } from 'vs/editor/common/config/commonEditorConfig'; @@ -27,12 +27,17 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { ansiColorIdentifiers, TERMINAL_BACKGROUND_COLOR, TERMINAL_FOREGROUND_COLOR, TERMINAL_CURSOR_FOREGROUND_COLOR, TERMINAL_CURSOR_BACKGROUND_COLOR, TERMINAL_SELECTION_BACKGROUND_COLOR } from 'vs/workbench/parts/terminal/common/terminalColorRegistry'; import { PANEL_BACKGROUND } from 'vs/workbench/common/theme'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; -import { INotificationService } from 'vs/platform/notification/common/notification'; +import { INotificationService, Severity, IPromptChoice } from 'vs/platform/notification/common/notification'; import { ILogService } from 'vs/platform/log/common/log'; import { TerminalCommandTracker } from 'vs/workbench/parts/terminal/node/terminalCommandTracker'; import { TerminalProcessManager } from './terminalProcessManager'; +import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; + +// How long in milliseconds should a frame take to render for a notification to appear which +// suggests the fallback DOM-based renderer +const SLOW_CANVAS_RENDER_THRESHOLD = 100; let Terminal: typeof XTermTerminal; @@ -41,6 +46,7 @@ export class TerminalInstance implements ITerminalInstance { private static _lastKnownDimensions: dom.Dimension = null; private static _idCounter = 1; + // private static _wasRenderTimeMeasured = false; private _processManager: ITerminalProcessManager | undefined; @@ -107,7 +113,8 @@ export class TerminalInstance implements ITerminalInstance { @IClipboardService private readonly _clipboardService: IClipboardService, @IThemeService private readonly _themeService: IThemeService, @IConfigurationService private readonly _configurationService: IConfigurationService, - @ILogService private _logService: ILogService + @ILogService private _logService: ILogService, + @IStorageService private readonly _storageService: IStorageService, ) { this._disposables = []; this._skipTerminalCommands = []; @@ -421,9 +428,53 @@ export class TerminalInstance implements ITerminalInstance { if (this._xterm.getOption('disableStdin')) { this._attachPressAnyKeyToCloseListener(); } + + const neverMeasureRenderTime = this._storageService.getBoolean(NEVER_MEASURE_RENDER_TIME_STORAGE_KEY, StorageScope.GLOBAL, false); + if (!neverMeasureRenderTime && this._configHelper.config.rendererType === 'auto') { + this._measureRenderTime(); + } }); } + private _measureRenderTime(): void { + // TODO: Only measure a few frames and then stop measuring. Do this once per session? + const renderer = (this._xterm).renderer; + const textRenderLayer = renderer._renderLayers[0]; + const originalOnGridChanged = textRenderLayer.onGridChanged; + textRenderLayer.onGridChanged = (terminal: XTermTerminal, firstRow: number, lastRow: number) => { + const startTime = performance.now(); + originalOnGridChanged.call(textRenderLayer, terminal, firstRow, lastRow); + const renderTimeMilliseconds = performance.now() - startTime; + if (renderTimeMilliseconds > SLOW_CANVAS_RENDER_THRESHOLD) { + const promptChoices: IPromptChoice[] = [ + { + label: nls.localize('yes', "Yes"), + run: () => { + this._configurationService.updateValue('terminal.integrated.rendererType', 'dom', ConfigurationTarget.USER).then(() => { + this._notificationService.info(nls.localize('terminal.rendererInAllNewTerminals', "All new terminals launched will use the non-GPU renderer.")); + }); + } + } as IPromptChoice, + { + label: nls.localize('no', "No") + } as IPromptChoice, + { + label: nls.localize('dontShowAgain', "Don't Show Again"), + isSecondary: true, + run: () => this._storageService.store(NEVER_MEASURE_RENDER_TIME_STORAGE_KEY, true) + } as IPromptChoice + ]; + this._notificationService.prompt( + Severity.Warning, + // TODO: Fill in link + nls.localize('terminal.slowRenderingNoLink', 'The terminal GPU-based rendering appears to be slow on your computer, do you want to use the fallback non-GPU renderer?'), + // nls.localize('terminal.slowRendering', 'The terminal GPU-based rendering appears to be slow on your computer, do you want to use the fallback non-GPU renderer? [Read more about terminal settings](https://code.visualstudio.com).'), + promptChoices + ); + } + }; + } + public registerLinkMatcher(regex: RegExp, handler: (url: string) => void, matchIndex?: number, validationCallback?: (uri: string, callback: (isValid: boolean) => void) => void): number { return this._linkHandler.registerCustomLinkHandler(regex, handler, matchIndex, validationCallback); } -- GitLab