Skip to content

Commit 02fa38c

Browse files
authored
Merge pull request #4244 from Tyriar/multi_page_atlas
Support multiple texture atlas pages
2 parents 43d8db7 + 4d05905 commit 02fa38c

File tree

15 files changed

+403
-185
lines changed

15 files changed

+403
-185
lines changed

addons/xterm-addon-canvas/src/BaseRenderLayer.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@ import { ReadonlyColorSet } from 'browser/Types';
1515
import { CellData } from 'common/buffer/CellData';
1616
import { WHITESPACE_CELL_CODE } from 'common/buffer/Constants';
1717
import { IBufferService, IDecorationService, IOptionsService } from 'common/services/Services';
18-
import { ICellData } from 'common/Types';
18+
import { ICellData, IDisposable } from 'common/Types';
1919
import { Terminal } from 'xterm';
2020
import { IRenderLayer } from './Types';
2121
import { CellColorResolver } from 'browser/renderer/shared/CellColorResolver';
2222
import { Disposable, toDisposable } from 'common/Lifecycle';
2323
import { isSafari } from 'common/Platform';
24+
import { EventEmitter, forwardEvent } from 'common/EventEmitter';
2425

2526
export abstract class BaseRenderLayer extends Disposable implements IRenderLayer {
2627
private _canvas: HTMLCanvasElement;
@@ -34,12 +35,16 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
3435

3536
protected _selectionModel: ISelectionRenderModel = createSelectionRenderModel();
3637
private _cellColorResolver: CellColorResolver;
37-
private _bitmapGenerator?: BitmapGenerator;
38+
private _bitmapGenerator: (BitmapGenerator | undefined)[] = [];
3839

3940
protected _charAtlas!: ITextureAtlas;
41+
private _charAtlasDisposable?: IDisposable;
4042

4143
public get canvas(): HTMLCanvasElement { return this._canvas; }
42-
public get cacheCanvas(): HTMLCanvasElement { return this._charAtlas?.cacheCanvas!; }
44+
public get cacheCanvas(): HTMLCanvasElement { return this._charAtlas?.pages[0].canvas!; }
45+
46+
private readonly _onAddTextureAtlasCanvas = this.register(new EventEmitter<HTMLCanvasElement>());
47+
public readonly onAddTextureAtlasCanvas = this._onAddTextureAtlasCanvas.event;
4348

4449
constructor(
4550
private readonly _terminal: Terminal,
@@ -116,9 +121,13 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
116121
if (this._deviceCharWidth <= 0 && this._deviceCharHeight <= 0) {
117122
return;
118123
}
124+
this._charAtlasDisposable?.dispose();
119125
this._charAtlas = acquireTextureAtlas(this._terminal, colorSet, this._deviceCellWidth, this._deviceCellHeight, this._deviceCharWidth, this._deviceCharHeight, this._coreBrowserService.dpr);
126+
this._charAtlasDisposable = forwardEvent(this._charAtlas.onAddTextureAtlasCanvas, this._onAddTextureAtlasCanvas);
120127
this._charAtlas.warmUp();
121-
this._bitmapGenerator = new BitmapGenerator(this._charAtlas.cacheCanvas);
128+
for (let i = 0; i < this._charAtlas.pages.length; i++) {
129+
this._bitmapGenerator[i] = new BitmapGenerator(this._charAtlas.pages[i].canvas);
130+
}
122131
}
123132

124133
public resize(dim: IRenderDimensions): void {
@@ -367,12 +376,15 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
367376
this._ctx.save();
368377
this._clipRow(y);
369378
// Draw the image, use the bitmap if it's available
370-
if (this._charAtlas.hasCanvasChanged) {
371-
this._bitmapGenerator?.refresh();
372-
this._charAtlas.hasCanvasChanged = false;
379+
if (this._charAtlas.pages[glyph.texturePage].hasCanvasChanged) {
380+
if (!this._bitmapGenerator[glyph.texturePage]) {
381+
this._bitmapGenerator[glyph.texturePage] = new BitmapGenerator(this._charAtlas.pages[glyph.texturePage].canvas);
382+
}
383+
this._bitmapGenerator[glyph.texturePage]?.refresh();
384+
this._charAtlas.pages[glyph.texturePage].hasCanvasChanged = false;
373385
}
374386
this._ctx.drawImage(
375-
this._bitmapGenerator?.bitmap || this._charAtlas!.cacheCanvas,
387+
this._bitmapGenerator[glyph.texturePage]?.bitmap || this._charAtlas!.pages[glyph.texturePage].canvas,
376388
glyph.texturePosition.x,
377389
glyph.texturePosition.y,
378390
glyph.size.x,

addons/xterm-addon-canvas/src/CanvasAddon.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ export class CanvasAddon extends Disposable implements ITerminalAddon {
1717

1818
private readonly _onChangeTextureAtlas = this.register(new EventEmitter<HTMLCanvasElement>());
1919
public readonly onChangeTextureAtlas = this._onChangeTextureAtlas.event;
20+
private readonly _onAddTextureAtlasCanvas = this.register(new EventEmitter<HTMLCanvasElement>());
21+
public readonly onAddTextureAtlasCanvas = this._onAddTextureAtlasCanvas.event;
2022

2123
public get textureAtlas(): HTMLCanvasElement | undefined {
2224
return this._renderer?.textureAtlas;
@@ -46,6 +48,7 @@ export class CanvasAddon extends Disposable implements ITerminalAddon {
4648

4749
this._renderer = new CanvasRenderer(terminal, screenElement, linkifier, bufferService, charSizeService, optionsService, characterJoinerService, coreService, coreBrowserService, decorationService, themeService);
4850
this.register(forwardEvent(this._renderer.onChangeTextureAtlas, this._onChangeTextureAtlas));
51+
this.register(forwardEvent(this._renderer.onAddTextureAtlasCanvas, this._onAddTextureAtlasCanvas));
4952
renderService.setRenderer(this._renderer);
5053
renderService.handleResize(bufferService.cols, bufferService.rows);
5154

addons/xterm-addon-canvas/src/CanvasRenderer.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { createRenderDimensions } from 'browser/renderer/shared/RendererUtils';
99
import { IRenderDimensions, IRenderer, IRequestRedrawEvent } from 'browser/renderer/shared/Types';
1010
import { ICharacterJoinerService, ICharSizeService, ICoreBrowserService, IThemeService } from 'browser/services/Services';
1111
import { ILinkifier2 } from 'browser/Types';
12-
import { EventEmitter } from 'common/EventEmitter';
12+
import { EventEmitter, forwardEvent } from 'common/EventEmitter';
1313
import { Disposable, toDisposable } from 'common/Lifecycle';
1414
import { IBufferService, ICoreService, IDecorationService, IOptionsService } from 'common/services/Services';
1515
import { Terminal } from 'xterm';
@@ -29,6 +29,8 @@ export class CanvasRenderer extends Disposable implements IRenderer {
2929
public readonly onRequestRedraw = this._onRequestRedraw.event;
3030
private readonly _onChangeTextureAtlas = this.register(new EventEmitter<HTMLCanvasElement>());
3131
public readonly onChangeTextureAtlas = this._onChangeTextureAtlas.event;
32+
private readonly _onAddTextureAtlasCanvas = this.register(new EventEmitter<HTMLCanvasElement>());
33+
public readonly onAddTextureAtlasCanvas = this._onAddTextureAtlasCanvas.event;
3234

3335
constructor(
3436
private readonly _terminal: Terminal,
@@ -51,6 +53,9 @@ export class CanvasRenderer extends Disposable implements IRenderer {
5153
new LinkRenderLayer(this._terminal, this._screenElement, 2, linkifier2, this._bufferService, this._optionsService, decorationService, this._coreBrowserService, _themeService),
5254
new CursorRenderLayer(this._terminal, this._screenElement, 3, this._onRequestRedraw, this._bufferService, this._optionsService, coreService, this._coreBrowserService, decorationService, _themeService)
5355
];
56+
for (const layer of this._renderLayers) {
57+
forwardEvent(layer.onAddTextureAtlasCanvas, this._onAddTextureAtlasCanvas);
58+
}
5459
this.dimensions = createRenderDimensions();
5560
this._devicePixelRatio = this._coreBrowserService.dpr;
5661
this._updateDimensions();

addons/xterm-addon-canvas/src/Types.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export interface IRenderLayer extends IDisposable {
4242
readonly canvas: HTMLCanvasElement;
4343
readonly cacheCanvas: HTMLCanvasElement;
4444

45+
readonly onAddTextureAtlasCanvas: IEvent<HTMLCanvasElement>;
4546
/**
4647
* Called when the terminal loses focus.
4748
*/

addons/xterm-addon-canvas/typings/xterm-addon-canvas.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ declare module 'xterm-addon-canvas' {
1717
*/
1818
public readonly onChangeTextureAtlas: IEvent<HTMLCanvasElement>;
1919

20+
/**
21+
* An event that is fired when the a new page is added to the texture atlas.
22+
*/
23+
public readonly onAddTextureAtlasCanvas: IEvent<HTMLCanvasElement>;
24+
2025
constructor();
2126

2227
/**

0 commit comments

Comments
 (0)