Skip to content
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
7 changes: 4 additions & 3 deletions addons/xterm-addon-canvas/src/BaseRenderLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -376,12 +376,12 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
this._ctx.save();
this._clipRow(y);
// Draw the image, use the bitmap if it's available
if (this._charAtlas.pages[glyph.texturePage].hasCanvasChanged) {
if (this._charAtlas.pages[glyph.texturePage].version !== this._bitmapGenerator[glyph.texturePage]?.version) {
if (!this._bitmapGenerator[glyph.texturePage]) {
this._bitmapGenerator[glyph.texturePage] = new BitmapGenerator(this._charAtlas.pages[glyph.texturePage].canvas);
}
this._bitmapGenerator[glyph.texturePage]?.refresh();
this._charAtlas.pages[glyph.texturePage].hasCanvasChanged = false;
this._bitmapGenerator[glyph.texturePage]!.refresh();
this._bitmapGenerator[glyph.texturePage]!.version = this._charAtlas.pages[glyph.texturePage].version;
}
this._ctx.drawImage(
this._bitmapGenerator[glyph.texturePage]?.bitmap || this._charAtlas!.pages[glyph.texturePage].canvas,
Expand Down Expand Up @@ -440,6 +440,7 @@ class BitmapGenerator {
private _commitTimeout: number | undefined = undefined;
private _bitmap: ImageBitmap | undefined = undefined;
public get bitmap(): ImageBitmap | undefined { return this._bitmap; }
public version: number = -1;

constructor(private readonly _canvas: HTMLCanvasElement) {
}
Expand Down
22 changes: 11 additions & 11 deletions addons/xterm-addon-webgl/src/GlyphRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @license MIT
*/

import { createProgram, PROJECTION_MATRIX } from './WebglUtils';
import { createProgram, GLTexture, PROJECTION_MATRIX } from './WebglUtils';
import { IWebGL2RenderingContext, IWebGLVertexArrayObject, IRenderModel } from './Types';
import { NULL_CELL_CODE } from 'common/buffer/Constants';
import { Terminal } from 'xterm';
Expand Down Expand Up @@ -94,7 +94,7 @@ export class GlyphRenderer extends Disposable {
private readonly _projectionLocation: WebGLUniformLocation;
private readonly _resolutionLocation: WebGLUniformLocation;
private readonly _textureLocation: WebGLUniformLocation;
private readonly _atlasTextures: WebGLTexture[];
private readonly _atlasTextures: GLTexture[];
private readonly _attributesBuffer: WebGLBuffer;

private _atlas: ITextureAtlas | undefined;
Expand Down Expand Up @@ -190,14 +190,14 @@ export class GlyphRenderer extends Disposable {
// is ever drawn it will show characters as red rectangles.
this._atlasTextures = [];
for (let i = 0; i < TextureAtlas.maxAtlasPages; i++) {
const texture = throwIfFalsy(gl.createTexture());
this.register(toDisposable(() => gl.deleteTexture(texture)));
const glTexture = new GLTexture(throwIfFalsy(gl.createTexture()));
this.register(toDisposable(() => gl.deleteTexture(glTexture.texture)));
gl.activeTexture(gl.TEXTURE0 + i);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.bindTexture(gl.TEXTURE_2D, glTexture.texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([255, 0, 0, 255]));
this._atlasTextures[i] = texture;
this._atlasTextures[i] = glTexture;
}

// Allow drawing of transparent texture
Expand Down Expand Up @@ -348,8 +348,7 @@ export class GlyphRenderer extends Disposable {

// Bind the atlas page texture if they have changed
for (let i = 0; i < this._atlas.pages.length; i++) {
if (this._atlas.pages[i].hasCanvasChanged) {
this._atlas.pages[i].hasCanvasChanged = false;
if (this._atlas.pages[i].version !== this._atlasTextures[i].version) {
this._bindAtlasPageTexture(gl, this._atlas, i);
}
}
Expand All @@ -360,18 +359,19 @@ export class GlyphRenderer extends Disposable {

public setAtlas(atlas: ITextureAtlas): void {
this._atlas = atlas;
for (let i = 0; i < atlas.pages.length; i++) {
this._bindAtlasPageTexture(this._gl, atlas, i);
for (const glTexture of this._atlasTextures) {
glTexture.version = -1;
}
}

private _bindAtlasPageTexture(gl: IWebGL2RenderingContext, atlas: ITextureAtlas, i: number): void {
gl.activeTexture(gl.TEXTURE0 + i);
gl.bindTexture(gl.TEXTURE_2D, this._atlasTextures[i]);
gl.bindTexture(gl.TEXTURE_2D, this._atlasTextures[i].texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, atlas.pages[i].canvas);
gl.generateMipmap(gl.TEXTURE_2D);
this._atlasTextures[i].version = atlas.pages[i].version;
}

public setDimensions(dimensions: IRenderDimensions): void {
Expand Down
10 changes: 10 additions & 0 deletions addons/xterm-addon-webgl/src/WebglUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,13 @@ export function expandFloat32Array(source: Float32Array, max: number): Float32Ar
}
return newArray;
}

export class GLTexture {
public texture: WebGLTexture;
public version: number;

constructor(texture: WebGLTexture) {
this.texture = texture;
this.version = -1;
}
}
15 changes: 7 additions & 8 deletions src/browser/renderer/shared/TextureAtlas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export class TextureAtlas implements ITextureAtlas {

// The texture that the atlas is drawn to
private _pages: AtlasPage[] = [];
public get pages(): { canvas: HTMLCanvasElement, hasCanvasChanged: boolean }[] { return this._pages; }
public get pages(): { canvas: HTMLCanvasElement, version: number }[] { return this._pages; }

// The set of atlas pages that can be written to
private _activePages: AtlasPage[] = [];
Expand Down Expand Up @@ -179,7 +179,7 @@ export class TextureAtlas implements ITextureAtlas {

// Merge into the new page
const mergedPage = this._mergePages(mergingPages, mergedPageIndex);
mergedPage.hasCanvasChanged = true;
mergedPage.version++;

// Replace the first _merging_ page with the _merged_ page
this._pages[mergedPageIndex] = mergedPage;
Expand Down Expand Up @@ -238,7 +238,7 @@ export class TextureAtlas implements ITextureAtlas {
for (const g of adjustingPage.glyphs) {
g.texturePage--;
}
adjustingPage.hasCanvasChanged = true;
adjustingPage.version++;
}
}

Expand Down Expand Up @@ -826,7 +826,7 @@ export class TextureAtlas implements ITextureAtlas {
rasterizedGlyph.size.y
);
activePage.addGlyph(rasterizedGlyph);
activePage.hasCanvasChanged = true;
activePage.version++;

return rasterizedGlyph;
}
Expand Down Expand Up @@ -936,10 +936,9 @@ class AtlasPage {
}

/**
* Whether the canvas of the atlas page has changed, this is only set to true by the atlas, the
* user of the boolean is required to reset its value to false.
* Used to check whether the canvas of the atlas page has changed.
*/
public hasCanvasChanged = false;
public version = 0;

// Texture atlas current positioning data. The texture packing strategy used is to fill from
// left-to-right and top-to-bottom. When the glyph being written is less than half of the current
Expand Down Expand Up @@ -982,7 +981,7 @@ class AtlasPage {
this.currentRow.y = 0;
this.currentRow.height = 0;
this.fixedRows.length = 0;
this.hasCanvasChanged = true;
this.version++;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/browser/renderer/shared/Types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export interface IRenderer extends IDisposable {
}

export interface ITextureAtlas extends IDisposable {
readonly pages: { canvas: HTMLCanvasElement, hasCanvasChanged: boolean }[];
readonly pages: { canvas: HTMLCanvasElement, version: number }[];

onAddTextureAtlasCanvas: IEvent<HTMLCanvasElement>;
onRemoveTextureAtlasCanvas: IEvent<HTMLCanvasElement>;
Expand Down