From a3321a617596355229bdbd9eaacc4411f634a645 Mon Sep 17 00:00:00 2001 From: Labhansh Agrawal Date: Sat, 25 Feb 2023 19:21:45 +0530 Subject: [PATCH] webgl --- addons/xterm-addon-webgl/src/GlyphRenderer.ts | 73 ++++++++++--------- addons/xterm-addon-webgl/src/WebglRenderer.ts | 11 +-- src/browser/renderer/shared/TextureAtlas.ts | 2 +- 3 files changed, 46 insertions(+), 40 deletions(-) diff --git a/addons/xterm-addon-webgl/src/GlyphRenderer.ts b/addons/xterm-addon-webgl/src/GlyphRenderer.ts index 91f2dc4fe6..caeb33c68e 100644 --- a/addons/xterm-addon-webgl/src/GlyphRenderer.ts +++ b/addons/xterm-addon-webgl/src/GlyphRenderer.ts @@ -84,6 +84,7 @@ const CELL_POSITION_INDICES = 2; // Work variables to avoid garbage collection let $i = 0; +let $j = 0; let $glyph: IRasterizedGlyph | undefined = undefined; let $glyphs: IRasterizedGlyph[] | undefined = undefined; let $leftCellPadding = 0; @@ -241,40 +242,44 @@ export class GlyphRenderer extends Disposable { } else { $glyphs = this._atlas.getRasterizedGlyph(code, bg, fg, ext); } - $glyph = $glyphs[0]; - - $leftCellPadding = Math.floor((this._dimensions.device.cell.width - this._dimensions.device.char.width) / 2); - if (bg !== lastBg && $glyph.offset.x > $leftCellPadding) { - $clippedPixels = $glyph.offset.x - $leftCellPadding; - // a_origin - array[$i ] = -($glyph.offset.x - $clippedPixels) + this._dimensions.device.char.left; - array[$i + 1] = -$glyph.offset.y + this._dimensions.device.char.top; - // a_size - array[$i + 2] = ($glyph.size.x - $clippedPixels) / this._dimensions.device.canvas.width; - array[$i + 3] = $glyph.size.y / this._dimensions.device.canvas.height; - // a_texpage - array[$i + 4] = $glyph.texturePage; - // a_texcoord - array[$i + 5] = $glyph.texturePositionClipSpace.x + $clippedPixels / this._atlas.pages[$glyph.texturePage].canvas.width; - array[$i + 6] = $glyph.texturePositionClipSpace.y; - // a_texsize - array[$i + 7] = $glyph.sizeClipSpace.x - $clippedPixels / this._atlas.pages[$glyph.texturePage].canvas.width; - array[$i + 8] = $glyph.sizeClipSpace.y; - } else { - // a_origin - array[$i ] = -$glyph.offset.x + this._dimensions.device.char.left; - array[$i + 1] = -$glyph.offset.y + this._dimensions.device.char.top; - // a_size - array[$i + 2] = $glyph.size.x / this._dimensions.device.canvas.width; - array[$i + 3] = $glyph.size.y / this._dimensions.device.canvas.height; - // a_texpage - array[$i + 4] = $glyph.texturePage; - // a_texcoord - array[$i + 5] = $glyph.texturePositionClipSpace.x; - array[$i + 6] = $glyph.texturePositionClipSpace.y; - // a_texsize - array[$i + 7] = $glyph.sizeClipSpace.x; - array[$i + 8] = $glyph.sizeClipSpace.y; + + for ($j = 0; $j < $glyphs.length; $j++) { + $i = (y * this._terminal.cols + x + $j) * INDICES_PER_CELL; + $glyph = $glyphs[$j]; + + $leftCellPadding = Math.floor((this._dimensions.device.cell.width - this._dimensions.device.char.width) / 2); + if (bg !== lastBg && $glyph.offset.x > $leftCellPadding) { + $clippedPixels = $glyph.offset.x - $leftCellPadding; + // a_origin + array[$i ] = -($glyph.offset.x - $clippedPixels) + this._dimensions.device.char.left; + array[$i + 1] = -$glyph.offset.y + this._dimensions.device.char.top; + // a_size + array[$i + 2] = ($glyph.size.x - $clippedPixels) / this._dimensions.device.canvas.width; + array[$i + 3] = $glyph.size.y / this._dimensions.device.canvas.height; + // a_texpage + array[$i + 4] = $glyph.texturePage; + // a_texcoord + array[$i + 5] = $glyph.texturePositionClipSpace.x + $clippedPixels / this._atlas.pages[$glyph.texturePage].canvas.width; + array[$i + 6] = $glyph.texturePositionClipSpace.y; + // a_texsize + array[$i + 7] = $glyph.sizeClipSpace.x - $clippedPixels / this._atlas.pages[$glyph.texturePage].canvas.width; + array[$i + 8] = $glyph.sizeClipSpace.y; + } else { + // a_origin + array[$i ] = -$glyph.offset.x + this._dimensions.device.char.left; + array[$i + 1] = -$glyph.offset.y + this._dimensions.device.char.top; + // a_size + array[$i + 2] = $glyph.size.x / this._dimensions.device.canvas.width; + array[$i + 3] = $glyph.size.y / this._dimensions.device.canvas.height; + // a_texpage + array[$i + 4] = $glyph.texturePage; + // a_texcoord + array[$i + 5] = $glyph.texturePositionClipSpace.x; + array[$i + 6] = $glyph.texturePositionClipSpace.y; + // a_texsize + array[$i + 7] = $glyph.sizeClipSpace.x; + array[$i + 8] = $glyph.sizeClipSpace.y; + } } // a_cellpos only changes on resize } diff --git a/addons/xterm-addon-webgl/src/WebglRenderer.ts b/addons/xterm-addon-webgl/src/WebglRenderer.ts index fcb0dd8096..2f29181ea4 100644 --- a/addons/xterm-addon-webgl/src/WebglRenderer.ts +++ b/addons/xterm-addon-webgl/src/WebglRenderer.ts @@ -366,6 +366,7 @@ export class WebglRenderer extends Disposable implements IRenderer { let i: number; let x: number; let j: number; + let k: number; start = clamp(start, terminal.rows - 1, 0); end = clamp(end, terminal.rows - 1, 0); for (y = start; y <= end; y++) { @@ -434,22 +435,22 @@ export class WebglRenderer extends Disposable implements IRenderer { this._model.cells[i + RENDER_MODEL_FG_OFFSET] = this._cellColorResolver.result.fg; this._model.cells[i + RENDER_MODEL_EXT_OFFSET] = this._cellColorResolver.result.ext; - this._glyphRenderer!.updateCell(x, y, code, this._cellColorResolver.result.bg, this._cellColorResolver.result.fg, this._cellColorResolver.result.ext, chars, lastBg); - if (isJoined) { // Restore work cell cell = this._workCell; // Null out non-first cells - for (x++; x < lastCharX; x++) { - j = ((y * terminal.cols) + x) * RENDER_MODEL_INDICIES_PER_CELL; - this._glyphRenderer!.updateCell(x, y, NULL_CELL_CODE, 0, 0, 0, NULL_CELL_CHAR, 0); + for (k = x + 1; k < lastCharX; k++) { + j = ((y * terminal.cols) + k) * RENDER_MODEL_INDICIES_PER_CELL; + this._glyphRenderer!.updateCell(k, y, NULL_CELL_CODE, 0, 0, 0, NULL_CELL_CHAR, 0); this._model.cells[j] = NULL_CELL_CODE; this._model.cells[j + RENDER_MODEL_BG_OFFSET] = this._cellColorResolver.result.bg; this._model.cells[j + RENDER_MODEL_FG_OFFSET] = this._cellColorResolver.result.fg; this._model.cells[j + RENDER_MODEL_EXT_OFFSET] = this._cellColorResolver.result.ext; } } + this._glyphRenderer!.updateCell(x, y, code, this._cellColorResolver.result.bg, this._cellColorResolver.result.fg, this._cellColorResolver.result.ext, chars, lastBg); + x = lastCharX; } } this._rectangleRenderer!.updateBackgrounds(this._model); diff --git a/src/browser/renderer/shared/TextureAtlas.ts b/src/browser/renderer/shared/TextureAtlas.ts index 6a89d30a66..c06f270b9e 100644 --- a/src/browser/renderer/shared/TextureAtlas.ts +++ b/src/browser/renderer/shared/TextureAtlas.ts @@ -685,7 +685,7 @@ export class TextureAtlas implements ITextureAtlas { // split the image into multiple images to fit into the texture const images: ImageData[] = []; if (this._tmpCanvas.width > this._textureSize) { - const step = this._textureSize-(2*padding); + const step = this._config.deviceCellWidth; const fullImageData = this._tmpCtx.getImageData(0, 0, this._tmpCanvas.width, this._tmpCanvas.height); if (!this._config.allowTransparency) {