From fc8043a25a80ee2ab711326c5c5e061a1cef2658 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sat, 8 Oct 2022 07:32:51 -0700 Subject: [PATCH] Ensure webgl texture atlas is released on dispose --- addons/xterm-addon-webgl/src/WebglRenderer.ts | 17 ++++++++--------- .../src/renderLayer/BaseRenderLayer.ts | 15 +++++++-------- .../src/renderLayer/LinkRenderLayer.ts | 5 +++-- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/addons/xterm-addon-webgl/src/WebglRenderer.ts b/addons/xterm-addon-webgl/src/WebglRenderer.ts index c3bb0616..6145d28f 100644 --- a/addons/xterm-addon-webgl/src/WebglRenderer.ts +++ b/addons/xterm-addon-webgl/src/WebglRenderer.ts @@ -14,7 +14,7 @@ import { AttributeData } from 'common/buffer/AttributeData'; import { CellData } from 'common/buffer/CellData'; import { Content, NULL_CELL_CHAR, NULL_CELL_CODE } from 'common/buffer/Constants'; import { EventEmitter } from 'common/EventEmitter'; -import { Disposable } from 'common/Lifecycle'; +import { Disposable, toDisposable } from 'common/Lifecycle'; import { ICoreService, IDecorationService } from 'common/services/Services'; import { CharData, IBufferLine, ICellData } from 'common/Types'; import { Terminal } from 'xterm'; @@ -131,15 +131,14 @@ export class WebglRenderer extends Disposable implements IRenderer { this._initializeWebGLState(); this._isAttached = this._coreBrowserService.window.document.body.contains(this._core.screenElement!); - } - public dispose(): void { - for (const l of this._renderLayers) { - l.dispose(); - } - this._canvas.parentElement?.removeChild(this._canvas); - removeTerminalFromCache(this._terminal); - super.dispose(); + this.register(toDisposable(() => { + for (const l of this._renderLayers) { + l.dispose(); + } + this._canvas.parentElement?.removeChild(this._canvas); + removeTerminalFromCache(this._terminal); + })); } public get textureAtlas(): HTMLCanvasElement | undefined { diff --git a/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts b/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts index 07eca0bf..58e23fc2 100644 --- a/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts +++ b/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts @@ -12,8 +12,9 @@ import { ICoreBrowserService } from 'browser/services/Services'; import { IRenderDimensions, ITextureAtlas } from 'browser/renderer/shared/Types'; import { CellData } from 'common/buffer/CellData'; import { throwIfFalsy } from 'browser/renderer/shared/RendererUtils'; +import { Disposable, toDisposable } from 'common/Lifecycle'; -export abstract class BaseRenderLayer implements IRenderLayer { +export abstract class BaseRenderLayer extends Disposable implements IRenderLayer { private _canvas: HTMLCanvasElement; protected _ctx!: CanvasRenderingContext2D; private _scaledCharWidth: number = 0; @@ -33,18 +34,16 @@ export abstract class BaseRenderLayer implements IRenderLayer { protected _colors: IColorSet, protected readonly _coreBrowserService: ICoreBrowserService ) { + super(); this._canvas = document.createElement('canvas'); this._canvas.classList.add(`xterm-${id}-layer`); this._canvas.style.zIndex = zIndex.toString(); this._initCanvas(); this._container.appendChild(this._canvas); - } - - public dispose(): void { - this._canvas.remove(); - if (this._charAtlas) { - this._charAtlas.dispose(); - } + this.register(toDisposable(() => { + this._canvas.remove(); + this._charAtlas?.dispose(); + })); } private _initCanvas(): void { diff --git a/addons/xterm-addon-webgl/src/renderLayer/LinkRenderLayer.ts b/addons/xterm-addon-webgl/src/renderLayer/LinkRenderLayer.ts index dbf2fdcf..15246348 100644 --- a/addons/xterm-addon-webgl/src/renderLayer/LinkRenderLayer.ts +++ b/addons/xterm-addon-webgl/src/renderLayer/LinkRenderLayer.ts @@ -10,6 +10,7 @@ import { ITerminal, IColorSet, ILinkifierEvent } from 'browser/Types'; import { IRenderDimensions } from 'browser/renderer/shared/Types'; import { ICoreBrowserService } from 'browser/services/Services'; import { is256Color } from 'browser/renderer/shared/CharAtlasUtils'; +import { toDisposable } from 'common/Lifecycle'; export class LinkRenderLayer extends BaseRenderLayer { private _state: ILinkifierEvent | undefined; @@ -23,8 +24,8 @@ export class LinkRenderLayer extends BaseRenderLayer { ) { super(container, 'link', zIndex, true, colors, coreBrowserService); - terminal.linkifier2.onShowLinkUnderline(e => this._onShowLinkUnderline(e)); - terminal.linkifier2.onHideLinkUnderline(e => this._onHideLinkUnderline(e)); + this.register(terminal.linkifier2.onShowLinkUnderline(e => this._onShowLinkUnderline(e))); + this.register(terminal.linkifier2.onHideLinkUnderline(e => this._onHideLinkUnderline(e))); } public resize(terminal: Terminal, dim: IRenderDimensions): void {