mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Fix exception when last 4 smallest pages are merged
This commit is contained in:
@@ -119,7 +119,9 @@ export class GlyphRenderer extends Disposable {
|
||||
const gl = this._gl;
|
||||
|
||||
if (TextureAtlas.maxAtlasPages === undefined) {
|
||||
// Typically 8 or 16
|
||||
TextureAtlas.maxAtlasPages = throwIfFalsy(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS) as number | null);
|
||||
// Almost all clients will support >= 4096
|
||||
TextureAtlas.maxTextureSize = throwIfFalsy(gl.getParameter(gl.MAX_TEXTURE_SIZE) as number | null);
|
||||
}
|
||||
|
||||
|
||||
@@ -150,12 +150,9 @@ export class TextureAtlas implements ITextureAtlas {
|
||||
// microtask to ensure it does not interrupt textures that will be rendered in the current
|
||||
// animation frame which would result in blank rendered areas. This is actually not that
|
||||
// expensive relative to drawing the glyphs, so there is no need to wait for an idle callback.
|
||||
if (TextureAtlas.maxAtlasPages && this._pages.length === TextureAtlas.maxAtlasPages - 1) {
|
||||
if (TextureAtlas.maxAtlasPages && this._pages.length >= Math.max(4, TextureAtlas.maxAtlasPages / 2)) {
|
||||
// TODO: If the viewport has enough glyphs to fill the new page, there will be a webgl error
|
||||
queueMicrotask(() => {
|
||||
console.time('merge');
|
||||
|
||||
// TODO: Track the most filled pages (pixels used of total) and use them?
|
||||
|
||||
// Migrate over 1 page at a time due to the time it takes to iterate over glyphs
|
||||
|
||||
// Find the set of the largest 4 images below the maximum size with the highest percentages used the 4 most used pages
|
||||
@@ -178,23 +175,15 @@ export class TextureAtlas implements ITextureAtlas {
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`4 at ${sameSizeI} of size ${size}`);
|
||||
|
||||
|
||||
// TODO: This is slow, need to sort after slice so _pages doesn't get sorted
|
||||
|
||||
const mergingPages = pagesBySize.slice(sameSizeI, sameSizeI + 4); // .sort((a, b) => a.percentageUsed < b.percentageUsed ? 1 : -1);
|
||||
console.log({ mergingPages });
|
||||
const sortedMergingPagesIndexes = mergingPages.map(e => e.glyphs[0].texturePage).sort((a, b) => a > b ? 1 : -1);
|
||||
// TODO: Pull texture page index in a nicer way
|
||||
const mergedPageIndex = sortedMergingPagesIndexes[0];
|
||||
|
||||
console.log({ mergedPageIndex, sortedMergingPagesIndexes: [...sortedMergingPagesIndexes] });
|
||||
|
||||
const mergedPage = this._mergePages(mergingPages, mergedPageIndex);
|
||||
|
||||
console.timeEnd('merge');
|
||||
|
||||
// (console as any).image(mergedPage.canvas);
|
||||
|
||||
mergedPage.hasCanvasChanged = true;
|
||||
@@ -202,8 +191,6 @@ export class TextureAtlas implements ITextureAtlas {
|
||||
// Replace an old merging page with the merged
|
||||
this._pages[mergedPageIndex] = mergedPage;
|
||||
|
||||
console.log('before adjust', this._pages);
|
||||
|
||||
// TODO: Splice other 3 pages, shifting all other texture page props
|
||||
for (let i = sortedMergingPagesIndexes.length - 1; i >= 1; i--) {
|
||||
this._deletePage(sortedMergingPagesIndexes[i]);
|
||||
@@ -723,6 +710,15 @@ export class TextureAtlas implements ITextureAtlas {
|
||||
let activePage: AtlasPage;
|
||||
let activeRow: ICharAtlasActiveRow;
|
||||
while (true) {
|
||||
// If there are no active pages (the last smallest 4 were merged), create a new one
|
||||
if (this._activePages.length === 0) {
|
||||
const newPage = this._createNewPage();
|
||||
activePage = newPage;
|
||||
activeRow = newPage.currentRow;
|
||||
activeRow.height = rasterizedGlyph.size.y;
|
||||
break;
|
||||
}
|
||||
|
||||
// Get the best current row from all active pages
|
||||
activePage = this._activePages[this._activePages.length - 1];
|
||||
activeRow = activePage.currentRow;
|
||||
|
||||
Reference in New Issue
Block a user