mirror of
https://github.com/stablyai/orca.git
synced 2026-11-13 09:27:29 +00:00
fix(terminal): bound WebGL atlas pages and release removed page textures (#39715)
Cap merged atlas pages at FORCED_MAX_TEXTURE_SIZE instead of the device MAX_TEXTURE_SIZE (16384 on Apple Silicon), stop the link render layer from acquiring the shared atlas with a mismatched 2048 texture size, and reset GL texture slots of removed atlas pages to the 1x1 placeholder. Mirrors xtermjs/xterm.js#6187, #6156 and #6306 in the addon-webgl source patch and regenerates the runtime patch and lock hash. Co-authored-by: FlamingoPg <1106310035@qq.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -32,7 +32,7 @@ index 49fdf5b1bb4d6c1f602e36470248a10a690a3479..384f4db6f22d0691f66938d42333d1b0
|
||||
if (code !== NULL_CELL_CODE && cell.extended.underlineStyle === UnderlineStyle.DOTTED) {
|
||||
const lineWidth = Math.max(1, Math.floor(this._optionService.rawOptions.fontSize * this._coreBrowserService.dpr / 15));
|
||||
diff --git a/src/GlyphRenderer.ts b/src/GlyphRenderer.ts
|
||||
index 742f0879ff4f04509e4a07c8efdf0d5743fe8ee5..885a206a394fff783737a412c0b75bf935dd0eca 100644
|
||||
index 742f0879ff4f04509e4a07c8efdf0d5743fe8ee5..21347443255cba3011e534248557239931ab7d47 100644
|
||||
--- a/src/GlyphRenderer.ts
|
||||
+++ b/src/GlyphRenderer.ts
|
||||
@@ -61,6 +61,8 @@ function createFragmentShaderSource(maxFragmentShaderTextureUnits: number): stri
|
||||
@@ -53,6 +53,30 @@ index 742f0879ff4f04509e4a07c8efdf0d5743fe8ee5..885a206a394fff783737a412c0b75bf9
|
||||
}`);
|
||||
}
|
||||
|
||||
@@ -102,6 +104,7 @@ export class GlyphRenderer extends Disposable {
|
||||
private _atlas: ITextureAtlas | undefined;
|
||||
private _lastSeenPageLayoutVersion: number = -1;
|
||||
private _pageOverflowWarned: boolean = false;
|
||||
+ private _uploadedTextureCount: number = 0;
|
||||
private _activeBuffer: number = 0;
|
||||
private readonly _vertices: IVertices = {
|
||||
count: 0,
|
||||
@@ -387,6 +390,15 @@ export class GlyphRenderer extends Disposable {
|
||||
this._bindAtlasPageTexture(gl, this._atlas, i);
|
||||
}
|
||||
}
|
||||
+ // Merging or evicting pages shrinks the page list, release the textures of pages that no
|
||||
+ // longer exist as they would otherwise keep their full size in GPU memory until reused.
|
||||
+ for (let i = pageCount; i < this._uploadedTextureCount; i++) {
|
||||
+ gl.activeTexture(gl.TEXTURE0 + i);
|
||||
+ gl.bindTexture(gl.TEXTURE_2D, this._atlasTextures[i].texture);
|
||||
+ 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].version = -1;
|
||||
+ }
|
||||
+ this._uploadedTextureCount = pageCount;
|
||||
|
||||
// Draw the viewport
|
||||
gl.drawElementsInstanced(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_BYTE, 0, bufferLength / Constants.INDICES_PER_CELL);
|
||||
diff --git a/src/RectangleRenderer.ts b/src/RectangleRenderer.ts
|
||||
index eebfda3b3df9b4c8cefcc6a64692053ed5eaeefa..75e34767bd1e12802b72371fddb5fc9028814e11 100644
|
||||
--- a/src/RectangleRenderer.ts
|
||||
@@ -78,7 +102,7 @@ index eebfda3b3df9b4c8cefcc6a64692053ed5eaeefa..75e34767bd1e12802b72371fddb5fc90
|
||||
this._updateRectangle(vertices, offset, currentFg, currentBg, currentStartX, terminal.cols, y);
|
||||
}
|
||||
diff --git a/src/TextureAtlas.ts b/src/TextureAtlas.ts
|
||||
index eff0d0e1c36906b1f14b85fb8db7907bf685c8a7..b4fcff8c6be49b1868a17bcabfa3bb54689fb8b1 100644
|
||||
index eff0d0e1c36906b1f14b85fb8db7907bf685c8a7..1fb0b7a971e33e1dbd2dcf9841645ca464617af2 100644
|
||||
--- a/src/TextureAtlas.ts
|
||||
+++ b/src/TextureAtlas.ts
|
||||
@@ -3,6 +3,7 @@
|
||||
@@ -156,6 +180,15 @@ index eff0d0e1c36906b1f14b85fb8db7907bf685c8a7..b4fcff8c6be49b1868a17bcabfa3bb54
|
||||
}
|
||||
|
||||
private _createNewPage(): AtlasPage {
|
||||
@@ -164,7 +172,7 @@ export class TextureAtlas implements ITextureAtlas {
|
||||
// Find the set of the largest 4 images, below the maximum size, with the highest
|
||||
// percentages used
|
||||
const pagesBySize = this._pages.filter(e => {
|
||||
- return e.canvas.width * 2 <= (TextureAtlas.maxTextureSize || Constants.FORCED_MAX_TEXTURE_SIZE);
|
||||
+ return e.canvas.width * 2 <= Math.min(TextureAtlas.maxTextureSize || Constants.FORCED_MAX_TEXTURE_SIZE, Constants.FORCED_MAX_TEXTURE_SIZE);
|
||||
}).sort((a, b) => {
|
||||
if (b.canvas.width !== a.canvas.width) {
|
||||
return b.canvas.width - a.canvas.width;
|
||||
@@ -468,6 +476,36 @@ export class TextureAtlas implements ITextureAtlas {
|
||||
return this._config.colors.contrastCache;
|
||||
}
|
||||
@@ -261,15 +294,78 @@ index 2d0f5a3a8ee7fc0765a0179cee0102edb9376e4b..92f1c7241e887cd907d21d91aa26c0de
|
||||
this._glyphRenderer.value.render(this._model);
|
||||
if (!this._cursorBlinkStateManager.value || this._cursorBlinkStateManager.value.isCursorVisible) {
|
||||
diff --git a/src/renderLayer/BaseRenderLayer.ts b/src/renderLayer/BaseRenderLayer.ts
|
||||
index 5b11615328957b6f5d41a174284c11e061910d91..1654e5ae39baf65a7243cbe7b1395c28824b269e 100644
|
||||
index 5b11615328957b6f5d41a174284c11e061910d91..00f299659106716258ad7b02c2bfdddcc53e91fe 100644
|
||||
--- a/src/renderLayer/BaseRenderLayer.ts
|
||||
+++ b/src/renderLayer/BaseRenderLayer.ts
|
||||
@@ -97,7 +97,7 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
|
||||
}
|
||||
@@ -3,8 +3,6 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
this._charAtlas = acquireTextureAtlas(terminal, this._optionsService.rawOptions, colorSet, this._deviceCellWidth, this._deviceCellHeight, this._deviceCharWidth, this._deviceCharHeight, this._coreBrowserService.dpr, 2048);
|
||||
- this._charAtlas.warmUp();
|
||||
+ this._charAtlas.warmUp(terminal.element);
|
||||
-import { ReadonlyColorSet } from 'browser/Types';
|
||||
-import { acquireTextureAtlas } from '../CharAtlasCache';
|
||||
import { IRenderDimensions } from 'browser/renderer/shared/Types';
|
||||
import { ICoreBrowserService, IThemeService } from 'browser/services/Services';
|
||||
import { Disposable, toDisposable } from 'common/Lifecycle';
|
||||
@@ -14,7 +12,6 @@ import { Terminal } from '@xterm/xterm';
|
||||
import { IRenderLayer } from './Types';
|
||||
import { throwIfFalsy } from 'browser/renderer/shared/RendererUtils';
|
||||
import { TEXT_BASELINE } from '../Constants';
|
||||
-import type { ITextureAtlas } from '../Types';
|
||||
|
||||
export abstract class BaseRenderLayer extends Disposable implements IRenderLayer {
|
||||
private _canvas: HTMLCanvasElement;
|
||||
@@ -26,8 +23,6 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
|
||||
private _deviceCharLeft: number = 0;
|
||||
private _deviceCharTop: number = 0;
|
||||
|
||||
- protected _charAtlas: ITextureAtlas | undefined;
|
||||
-
|
||||
constructor(
|
||||
terminal: Terminal,
|
||||
private _container: HTMLElement,
|
||||
@@ -44,8 +39,7 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
|
||||
this._canvas.style.zIndex = zIndex.toString();
|
||||
this._initCanvas();
|
||||
this._container.appendChild(this._canvas);
|
||||
- this._register(this._themeService.onChangeColors(e => {
|
||||
- this._refreshCharAtlas(terminal, e);
|
||||
+ this._register(this._themeService.onChangeColors(() => {
|
||||
this.reset(terminal);
|
||||
}));
|
||||
this._register(toDisposable(() => {
|
||||
@@ -81,25 +75,10 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
|
||||
this._initCanvas();
|
||||
this._container.replaceChild(this._canvas, oldCanvas);
|
||||
|
||||
- // Regenerate char atlas and force a full redraw
|
||||
- this._refreshCharAtlas(terminal, this._themeService.colors);
|
||||
+ // Force a full redraw
|
||||
this.handleGridChanged(terminal, 0, terminal.rows - 1);
|
||||
}
|
||||
|
||||
- /**
|
||||
- * Refreshes the char atlas, aquiring a new one if necessary.
|
||||
- * @param terminal The terminal.
|
||||
- * @param colorSet The color set to use for the char atlas.
|
||||
- */
|
||||
- private _refreshCharAtlas(terminal: Terminal, colorSet: ReadonlyColorSet): void {
|
||||
- if (this._deviceCharWidth <= 0 && this._deviceCharHeight <= 0) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- this._charAtlas = acquireTextureAtlas(terminal, this._optionsService.rawOptions, colorSet, this._deviceCellWidth, this._deviceCellHeight, this._deviceCharWidth, this._deviceCharHeight, this._coreBrowserService.dpr, 2048);
|
||||
- this._charAtlas.warmUp();
|
||||
- }
|
||||
-
|
||||
public resize(terminal: Terminal, dim: IRenderDimensions): void {
|
||||
this._deviceCellWidth = dim.device.cell.width;
|
||||
this._deviceCellHeight = dim.device.cell.height;
|
||||
@@ -116,8 +95,6 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
|
||||
if (!this._alpha) {
|
||||
this._clearAll();
|
||||
}
|
||||
-
|
||||
- this._refreshCharAtlas(terminal, this._themeService.colors);
|
||||
}
|
||||
|
||||
public abstract reset(terminal: Terminal): void;
|
||||
|
||||
Generated
+3
-3
@@ -205,7 +205,7 @@ patchedDependencies:
|
||||
'@xterm/addon-ligatures@0.11.0-beta.330': 47405b9994b5acf1b4e90b49250358c1ca03649854d59560e7732b72fe336920
|
||||
'@xterm/addon-search@0.17.0-beta.330': eee5338dd2621ece46e79c61ec06766cd7fadaf79ffdb24e2a8ab68e97ef31f0
|
||||
'@xterm/addon-serialize@0.15.0-beta.330': 17ca66ab9c7f52fc2fee94053b3b587c1210da468f3ddc7c4f5dba50b521c93e
|
||||
'@xterm/addon-webgl@0.20.0-beta.329': a12343c037a1a504d80da0a0bbdbbdc7ce3440a088021a95da1dd6f62b98d110
|
||||
'@xterm/addon-webgl@0.20.0-beta.329': 0d63e956bc68b3f56942e2ed9325e2bf2b1dab76ab403a0690b94232b5ef4aab
|
||||
'@xterm/xterm@6.1.0-beta.336': 4b7fbfe7a7f626843ab88535cc6e2181872ea7c107876b15406a295182bc3c2c
|
||||
glob@13.0.6: 163edae2cab27bf7a8cf791c9a0ee368b596bfef898e490b3b77e7e44a8f0223
|
||||
i18next-cli@1.74.2: 2ee32eef742615cd133e1a6940f027deb3723a8430bb7953bba3a6769b0aac47
|
||||
@@ -463,7 +463,7 @@ importers:
|
||||
version: 0.13.0-beta.330(@xterm/xterm@6.1.0-beta.336(patch_hash=4b7fbfe7a7f626843ab88535cc6e2181872ea7c107876b15406a295182bc3c2c))
|
||||
'@xterm/addon-webgl':
|
||||
specifier: 0.20.0-beta.329
|
||||
version: 0.20.0-beta.329(patch_hash=a12343c037a1a504d80da0a0bbdbbdc7ce3440a088021a95da1dd6f62b98d110)(@xterm/xterm@6.1.0-beta.336(patch_hash=4b7fbfe7a7f626843ab88535cc6e2181872ea7c107876b15406a295182bc3c2c))
|
||||
version: 0.20.0-beta.329(patch_hash=0d63e956bc68b3f56942e2ed9325e2bf2b1dab76ab403a0690b94232b5ef4aab)(@xterm/xterm@6.1.0-beta.336(patch_hash=4b7fbfe7a7f626843ab88535cc6e2181872ea7c107876b15406a295182bc3c2c))
|
||||
'@xterm/xterm':
|
||||
specifier: 6.1.0-beta.336
|
||||
version: 6.1.0-beta.336(patch_hash=4b7fbfe7a7f626843ab88535cc6e2181872ea7c107876b15406a295182bc3c2c)
|
||||
@@ -11386,7 +11386,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@xterm/xterm': 6.1.0-beta.336(patch_hash=4b7fbfe7a7f626843ab88535cc6e2181872ea7c107876b15406a295182bc3c2c)
|
||||
|
||||
'@xterm/addon-webgl@0.20.0-beta.329(patch_hash=a12343c037a1a504d80da0a0bbdbbdc7ce3440a088021a95da1dd6f62b98d110)(@xterm/xterm@6.1.0-beta.336(patch_hash=4b7fbfe7a7f626843ab88535cc6e2181872ea7c107876b15406a295182bc3c2c))':
|
||||
'@xterm/addon-webgl@0.20.0-beta.329(patch_hash=0d63e956bc68b3f56942e2ed9325e2bf2b1dab76ab403a0690b94232b5ef4aab)(@xterm/xterm@6.1.0-beta.336(patch_hash=4b7fbfe7a7f626843ab88535cc6e2181872ea7c107876b15406a295182bc3c2c))':
|
||||
dependencies:
|
||||
'@xterm/xterm': 6.1.0-beta.336(patch_hash=4b7fbfe7a7f626843ab88535cc6e2181872ea7c107876b15406a295182bc3c2c)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user