Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add onContextLoss to webgl addon #3276

Merged
merged 6 commits into from
Apr 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions addons/xterm-addon-webgl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,18 @@ terminal.loadAddon(new WebglAddon());
```

See the full [API](https://github.com/xtermjs/xterm.js/blob/master/addons/xterm-addon-webgl/typings/xterm-addon-webgl.d.ts) for more advanced usage.

### Handling Context Loss

The browser may drop WebGL contexts for various reasons like OOM or after the system has been suspended. There is an API exposed that fires the `webglcontextlost` event fired on the canvas so embedders can handle it however they wish. An easy, but suboptimal way, to handle this is by disposing of WebglAddon when the event fires:

```ts
const terminal = new Terminal();
const addon = new WebglAddon();
addon.onContextLoss(e => {
addon.dispose();
});
terminal.loadAddon(addon);
```

Read more about handling WebGL context losses on the [Khronos wiki](https://www.khronos.org/webgl/wiki/HandlingContextLost).
6 changes: 5 additions & 1 deletion addons/xterm-addon-webgl/src/WebglAddon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
* @license MIT
*/

import { Terminal, ITerminalAddon } from 'xterm';
import { Terminal, ITerminalAddon, IEvent } from 'xterm';
import { WebglRenderer } from './WebglRenderer';
import { IRenderService } from 'browser/services/Services';
import { IColorSet } from 'browser/Types';
import { EventEmitter } from 'common/EventEmitter';

export class WebglAddon implements ITerminalAddon {
private _terminal?: Terminal;
private _renderer?: WebglRenderer;
private _onContextLoss = new EventEmitter<void>();
public get onContextLoss(): IEvent<void> { return this._onContextLoss.event; }

constructor(
private _preserveDrawingBuffer?: boolean
Expand All @@ -24,6 +27,7 @@ export class WebglAddon implements ITerminalAddon {
const renderService: IRenderService = (<any>terminal)._core._renderService;
const colors: IColorSet = (<any>terminal)._core._colorManager.colors;
this._renderer = new WebglRenderer(terminal, colors, this._preserveDrawingBuffer);
this._renderer.onContextLoss(() => this._onContextLoss.fire());
renderService.setRenderer(this._renderer);
}

Expand Down
7 changes: 7 additions & 0 deletions addons/xterm-addon-webgl/src/WebglRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { IRenderDimensions, IRenderer, IRequestRedrawEvent } from 'browser/rende
import { ITerminal, IColorSet } from 'browser/Types';
import { EventEmitter } from 'common/EventEmitter';
import { CellData } from 'common/buffer/CellData';
import { addDisposableDomListener } from 'browser/Lifecycle';

export class WebglRenderer extends Disposable implements IRenderer {
private _renderLayers: IRenderLayer[];
Expand All @@ -41,6 +42,9 @@ export class WebglRenderer extends Disposable implements IRenderer {
private _onRequestRedraw = new EventEmitter<IRequestRedrawEvent>();
public get onRequestRedraw(): IEvent<IRequestRedrawEvent> { return this._onRequestRedraw.event; }

private _onContextLoss = new EventEmitter<void>();
public get onContextLoss(): IEvent<void> { return this._onContextLoss.event; }

constructor(
private _terminal: Terminal,
private _colors: IColorSet,
Expand Down Expand Up @@ -82,6 +86,9 @@ export class WebglRenderer extends Disposable implements IRenderer {
if (!this._gl) {
throw new Error('WebGL2 not supported ' + this._gl);
}

this.register(addDisposableDomListener(this._canvas, 'webglcontextlost', (e) => { this._onContextLoss.fire(e); }));

this._core.screenElement!.appendChild(this._canvas);

this._rectangleRenderer = new RectangleRenderer(this._terminal, this._colors, this._gl, this.dimensions);
Expand Down
6 changes: 6 additions & 0 deletions addons/xterm-addon-webgl/typings/xterm-addon-webgl.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* @license MIT
*/

import { IEvent } from 'node-pty';
import { Terminal, ITerminalAddon } from 'xterm';

declare module 'xterm-addon-webgl' {
Expand All @@ -29,5 +30,10 @@ declare module 'xterm-addon-webgl' {
* Clears the terminal's texture atlas and triggers a redraw.
*/
public clearTextureAtlas(): void;

/**
* Fired when the WebglRenderer loses context
*/
public get onContextLoss(): IEvent<void>;
}
}