mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Support up to maximum texture units (eg. 16 on my machine)
This commit is contained in:
@@ -56,40 +56,31 @@ void main() {
|
||||
v_texcoord = a_texcoord + a_unitquad * a_texsize;
|
||||
}`;
|
||||
|
||||
const fragmentShaderSource = `#version 300 es
|
||||
function createFragmentShaderSource(maxFragmentShaderTextureUnits: number): string {
|
||||
let textureConditionals = '';
|
||||
for (let i = 1; i < maxFragmentShaderTextureUnits; i++) {
|
||||
textureConditionals += ` else if (v_texpage == ${i}) { outColor = texture(u_texture[${i}], v_texcoord); }`;
|
||||
}
|
||||
return (`#version 300 es
|
||||
precision lowp float;
|
||||
|
||||
in vec2 v_texcoord;
|
||||
flat in int v_texpage;
|
||||
|
||||
uniform sampler2D u_texture[8];
|
||||
uniform sampler2D u_texture[${maxFragmentShaderTextureUnits}];
|
||||
|
||||
out vec4 outColor;
|
||||
|
||||
void main() {
|
||||
if (v_texpage == 0) {
|
||||
outColor = texture(u_texture[0], v_texcoord);
|
||||
} else if (v_texpage == 1) {
|
||||
outColor = texture(u_texture[1], v_texcoord);
|
||||
} else if (v_texpage == 2) {
|
||||
outColor = texture(u_texture[2], v_texcoord);
|
||||
} else if (v_texpage == 3) {
|
||||
outColor = texture(u_texture[3], v_texcoord);
|
||||
} else if (v_texpage == 4) {
|
||||
outColor = texture(u_texture[4], v_texcoord);
|
||||
} else if (v_texpage == 5) {
|
||||
outColor = texture(u_texture[5], v_texcoord);
|
||||
} else if (v_texpage == 6) {
|
||||
outColor = texture(u_texture[6], v_texcoord);
|
||||
} else if (v_texpage == 7) {
|
||||
outColor = texture(u_texture[7], v_texcoord);
|
||||
}
|
||||
}`;
|
||||
} ${textureConditionals}
|
||||
}`);
|
||||
}
|
||||
|
||||
const INDICES_PER_CELL = 11;
|
||||
const BYTES_PER_CELL = INDICES_PER_CELL * Float32Array.BYTES_PER_ELEMENT;
|
||||
const CELL_POSITION_INDICES = 2;
|
||||
const MAX_ATLAS_PAGES = 8;
|
||||
|
||||
// Work variables to avoid garbage collection
|
||||
let $i = 0;
|
||||
@@ -117,15 +108,21 @@ export class GlyphRenderer extends Disposable {
|
||||
]
|
||||
};
|
||||
|
||||
private static _maxAtlasPages: number | undefined;
|
||||
|
||||
constructor(
|
||||
private _terminal: Terminal,
|
||||
private _gl: IWebGL2RenderingContext,
|
||||
private readonly _terminal: Terminal,
|
||||
private readonly _gl: IWebGL2RenderingContext,
|
||||
private _dimensions: IRenderDimensions
|
||||
) {
|
||||
super();
|
||||
|
||||
const gl = this._gl;
|
||||
this._program = throwIfFalsy(createProgram(gl, vertexShaderSource, fragmentShaderSource));
|
||||
|
||||
if (GlyphRenderer._maxAtlasPages === undefined) {
|
||||
GlyphRenderer._maxAtlasPages = throwIfFalsy(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS) as number | null);
|
||||
}
|
||||
this._program = throwIfFalsy(createProgram(gl, vertexShaderSource, createFragmentShaderSource(GlyphRenderer._maxAtlasPages)));
|
||||
this.register(toDisposable(() => gl.deleteProgram(this._program)));
|
||||
|
||||
// Uniform locations
|
||||
@@ -180,13 +177,17 @@ export class GlyphRenderer extends Disposable {
|
||||
|
||||
// Setup static uniforms
|
||||
gl.useProgram(this._program);
|
||||
gl.uniform1iv(this._textureLocation, new Int32Array([0, 1, 2, 3, 4, 5, 6, 7]));
|
||||
const textureUnits = new Int32Array(GlyphRenderer._maxAtlasPages);
|
||||
for (let i = 0; i < GlyphRenderer._maxAtlasPages; i++) {
|
||||
textureUnits[i] = i;
|
||||
}
|
||||
gl.uniform1iv(this._textureLocation, textureUnits);
|
||||
gl.uniformMatrix4fv(this._projectionLocation, false, PROJECTION_MATRIX);
|
||||
|
||||
// Setup 1x1 red pixel textures for all potential atlas pages, if one of these invalid textures
|
||||
// is ever drawn it will show characters as red rectangles.
|
||||
this._atlasTextures = [];
|
||||
for (let i = 0; i < MAX_ATLAS_PAGES; i++) {
|
||||
for (let i = 0; i < GlyphRenderer._maxAtlasPages; i++) {
|
||||
const texture = throwIfFalsy(gl.createTexture());
|
||||
this.register(toDisposable(() => gl.deleteTexture(texture)));
|
||||
gl.activeTexture(gl.TEXTURE0 + i);
|
||||
|
||||
@@ -219,6 +219,7 @@ if (document.location.pathname === '/test') {
|
||||
document.getElementById('htmlserialize').addEventListener('click', htmlSerializeButtonHandler);
|
||||
document.getElementById('custom-glyph').addEventListener('click', writeCustomGlyphHandler);
|
||||
document.getElementById('load-test').addEventListener('click', loadTest);
|
||||
document.getElementById('print-cjk').addEventListener('click', addCjk);
|
||||
document.getElementById('powerline-symbol-test').addEventListener('click', powerlineSymbolTest);
|
||||
document.getElementById('underline-test').addEventListener('click', underlineTest);
|
||||
document.getElementById('ansi-colors').addEventListener('click', ansiColorsTest);
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
|
||||
<dt>Performance</dt>
|
||||
<dd><button id="load-test" title="Write several MB of data to simulate a lot of data coming from the process">Load test</button></dd>
|
||||
<dd><button id="print-cjk" title="Prints the 20977 characters from the CJK Unified Ideographs unicode block">CJK Unified Ideographs</button></dd>
|
||||
|
||||
<dt>Styles</dt>
|
||||
<dd><button id="custom-glyph" title="Write custom box drawing and block element characters to the terminal">Test custom glyphs</button></dd>
|
||||
|
||||
@@ -122,7 +122,6 @@ export class TextureAtlas implements ITextureAtlas {
|
||||
// room for a new row
|
||||
if (page.currentRow.y > Math.floor(page.canvas.height * 0.8)) {
|
||||
// TODO: Clear all pages and restart if the maximum page count is reached
|
||||
console.log(`Add page #${this._pages.length + 1}`);
|
||||
const newPage = new AtlasPage(this._document, this._config.devicePixelRatio);
|
||||
this._pages.push(newPage);
|
||||
this._activePages.push(newPage);
|
||||
@@ -701,7 +700,6 @@ export class TextureAtlas implements ITextureAtlas {
|
||||
|
||||
// Exit the loop if there is enough room in the row
|
||||
if (activeRow.x + rasterizedGlyph.size.x <= activePage.canvas.width) {
|
||||
console.log(`draw "${chars}" to row ${activeRow} on page ${this._pages.indexOf(activePage)}`);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user