mirror of
https://github.com/stablyai/orca.git
synced 2026-09-21 16:02:20 +00:00
test(terminal): prove empty glyph eviction preserves visible caches
This commit is contained in:
@@ -95,6 +95,9 @@ design-docs/
|
||||
# and the tracked reference docs linked from AGENTS.md / README.md).
|
||||
docs/**
|
||||
!docs/
|
||||
!docs/audits/
|
||||
!docs/audits/webgl-empty-glyph-retention/
|
||||
!docs/audits/webgl-empty-glyph-retention/**
|
||||
# The deployable docs app is source, not local engineering notes.
|
||||
!docs/site/
|
||||
!docs/site/**
|
||||
|
||||
@@ -37,6 +37,24 @@ describe('vendored xterm WebGL runtime contract', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it('keeps invisible glyph eviction separate from the visible glyph cache', () => {
|
||||
const webgl = xtermManifest.packages.find((entry) => entry.name === '@xterm/addon-webgl')
|
||||
for (const source of [
|
||||
readProject(webgl.sourcePatch),
|
||||
readInstalled('@xterm/addon-webgl', 'src/TextureAtlas.ts')
|
||||
]) {
|
||||
expect(source).toContain('emptyCacheMap.get(key, bg, fg, ext)')
|
||||
expect(source).toContain('this._emptyGlyphCount >= Constants.EMPTY_GLYPH_CACHE_LIMIT')
|
||||
expect(source).toContain('this._clearEmptyGlyphCache()')
|
||||
}
|
||||
for (const bundle of ['lib/addon-webgl.js', 'lib/addon-webgl.mjs']) {
|
||||
const contents = readInstalled('@xterm/addon-webgl', bundle)
|
||||
expect(contents, bundle).toContain('_emptyCacheMapCombined')
|
||||
expect(contents, bundle).toContain('_clearEmptyGlyphCache')
|
||||
expect(contents, bundle).toMatch(/_emptyGlyphCount>=4096/)
|
||||
}
|
||||
})
|
||||
|
||||
it('keeps the Orca-only WebGL hunks in the generated patch', () => {
|
||||
const webgl = xtermManifest.packages.find((entry) => entry.name === '@xterm/addon-webgl')
|
||||
const patch = readProject(webgl.patch)
|
||||
|
||||
@@ -38,7 +38,8 @@ two modes. It samples V8 heap after CDP collection and records bundle hashes in
|
||||
[results.json](./results.json). Two terminals share one atlas. Assertions cover:
|
||||
|
||||
- Invisible entries stay at or below 4,096; the baseline accumulates 100,000.
|
||||
- Visible glyph caches and the one texture page stay intact across overflow.
|
||||
- After ASCII warmup finishes, visible cache and glyph counts stay exactly unchanged
|
||||
across overflow, with no visible glyph rerasterized; the one texture page stays intact.
|
||||
- Rendered pixels for the unaffected first cell of both terminals stay identical.
|
||||
- The last 64 repeated variants cause no new rasterization.
|
||||
- Explicit clear drops invisible metadata even when the atlas has no drawn glyphs.
|
||||
@@ -48,7 +49,13 @@ run ends with 1,789 entries (93 visible and 1,696 invisible), with roughly 0.3 M
|
||||
of heap growth. Exact heap samples vary; the bounded entry count is the invariant.
|
||||
No Orca window was launched, and no browser window was shown.
|
||||
|
||||
Validation also passed 86 tests across the patch generator/runtime contract and
|
||||
A follow-up [review-validation.json](./review-validation.json) reruns both installed
|
||||
bundles and both output modes with the stronger warmup/count/rasterization checks
|
||||
on Node 24.20.0. The original before/after measurements above remain in `results.json`.
|
||||
The runtime contract test also guards the empty-glyph routing and cap in the source
|
||||
patch, installed source, and both shipped bundles. Its three checks pass.
|
||||
|
||||
Original validation also passed 86 tests across the patch generator/runtime contract and
|
||||
WebGL lifecycle/context/recovery suites, full typecheck, lint, and changed-code
|
||||
quality. Test commands used `ORCA_BACKGROUND_LAUNCH=1`.
|
||||
|
||||
|
||||
@@ -65,6 +65,21 @@ try {
|
||||
await new Promise(requestAnimationFrame)
|
||||
await new Promise(requestIdleCallback)
|
||||
}, mode)
|
||||
// The atlas warms ASCII in idle tasks; sample only after the final queued glyph exists.
|
||||
await page.waitForFunction(() =>
|
||||
Boolean(window.glyphAudit.first.addon._renderer._charAtlas._cacheMap.get(125, 0, 0, 0))
|
||||
)
|
||||
await page.evaluate(() => {
|
||||
const atlas = window.glyphAudit.first.addon._renderer._charAtlas
|
||||
const draw = atlas._drawToCache
|
||||
window.glyphAudit.visibleRasterizations = 0
|
||||
atlas._drawToCache = function (...args) {
|
||||
if (args[0] !== 32 && args[0] !== ' \u200d') {
|
||||
window.glyphAudit.visibleRasterizations++
|
||||
}
|
||||
return draw.apply(this, args)
|
||||
}
|
||||
})
|
||||
const cdp = await page.context().newCDPSession(page)
|
||||
const samples = []
|
||||
for (const count of [0, 1000, 5000, 10000, 50000, 100000]) {
|
||||
@@ -81,6 +96,7 @@ try {
|
||||
second.addon._renderer.renderRows(0, 0)
|
||||
window.glyphAudit.index = count
|
||||
const atlas = first.addon._renderer._charAtlas
|
||||
// This audit is tied to the pinned addon's private FourKeyMap storage.
|
||||
const entries = (map) => {
|
||||
let result = 0
|
||||
for (const second of Object.values(map?._data._data ?? {})) {
|
||||
@@ -106,6 +122,7 @@ try {
|
||||
}
|
||||
return {
|
||||
updates: count,
|
||||
visibleRasterizations: window.glyphAudit.visibleRasterizations,
|
||||
firstCellPixels: pixels(first),
|
||||
secondCellPixels: pixels(second),
|
||||
regular: entries(atlas._cacheMap),
|
||||
@@ -160,7 +177,12 @@ try {
|
||||
if (phase === 'after') {
|
||||
assert.ok(
|
||||
samples.every(
|
||||
(sample) => sample.empty <= 4096 && sample.regular + sample.combined < 200
|
||||
(sample) =>
|
||||
sample.empty <= 4096 &&
|
||||
sample.regular === samples[0].regular &&
|
||||
sample.combined === samples[0].combined &&
|
||||
sample.glyphs === samples[0].glyphs &&
|
||||
sample.visibleRasterizations === 0
|
||||
)
|
||||
)
|
||||
assert.equal(checks.emptyAfterClear, 0)
|
||||
|
||||
@@ -0,0 +1,414 @@
|
||||
{
|
||||
"node": "v24.20.0",
|
||||
"browser": "146.0.7680.0",
|
||||
"results": [
|
||||
{
|
||||
"phase": "after",
|
||||
"format": "cjs",
|
||||
"mode": "space",
|
||||
"sha256": "0667d4850345c52271515c6ffe434c40687c59db007ddd32aabc02f0118a1cad",
|
||||
"samples": [
|
||||
{
|
||||
"updates": 0,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 0,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3336616
|
||||
},
|
||||
{
|
||||
"updates": 1000,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 1000,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3808452
|
||||
},
|
||||
{
|
||||
"updates": 5000,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 904,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3799644
|
||||
},
|
||||
{
|
||||
"updates": 10000,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 1808,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3918852
|
||||
},
|
||||
{
|
||||
"updates": 50000,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 848,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3519764
|
||||
},
|
||||
{
|
||||
"updates": 100000,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 1696,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3632676
|
||||
}
|
||||
],
|
||||
"checks": {
|
||||
"rasterizations": 0,
|
||||
"emptyAfterClear": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"phase": "after",
|
||||
"format": "cjs",
|
||||
"mode": "space-joiner",
|
||||
"sha256": "0667d4850345c52271515c6ffe434c40687c59db007ddd32aabc02f0118a1cad",
|
||||
"samples": [
|
||||
{
|
||||
"updates": 0,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 0,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3336388
|
||||
},
|
||||
{
|
||||
"updates": 1000,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 1000,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3788324
|
||||
},
|
||||
{
|
||||
"updates": 5000,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 904,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3817620
|
||||
},
|
||||
{
|
||||
"updates": 10000,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 1808,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3937304
|
||||
},
|
||||
{
|
||||
"updates": 50000,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 848,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3855688
|
||||
},
|
||||
{
|
||||
"updates": 100000,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 1696,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3653104
|
||||
}
|
||||
],
|
||||
"checks": {
|
||||
"rasterizations": 0,
|
||||
"emptyAfterClear": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"phase": "after",
|
||||
"format": "esm",
|
||||
"mode": "space",
|
||||
"sha256": "1ff2a59921ed5d53c0958110dac290c8d9f8d4502ea631fac7fd8575227b30f0",
|
||||
"samples": [
|
||||
{
|
||||
"updates": 0,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 0,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3295588
|
||||
},
|
||||
{
|
||||
"updates": 1000,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 1000,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3768188
|
||||
},
|
||||
{
|
||||
"updates": 5000,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 904,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3759512
|
||||
},
|
||||
{
|
||||
"updates": 10000,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 1808,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3878776
|
||||
},
|
||||
{
|
||||
"updates": 50000,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 848,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3798292
|
||||
},
|
||||
{
|
||||
"updates": 100000,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 1696,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3668712
|
||||
}
|
||||
],
|
||||
"checks": {
|
||||
"rasterizations": 0,
|
||||
"emptyAfterClear": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"phase": "after",
|
||||
"format": "esm",
|
||||
"mode": "space-joiner",
|
||||
"sha256": "1ff2a59921ed5d53c0958110dac290c8d9f8d4502ea631fac7fd8575227b30f0",
|
||||
"samples": [
|
||||
{
|
||||
"updates": 0,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 0,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3286928
|
||||
},
|
||||
{
|
||||
"updates": 1000,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 1000,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3783224
|
||||
},
|
||||
{
|
||||
"updates": 5000,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 904,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3777172
|
||||
},
|
||||
{
|
||||
"updates": 10000,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 1808,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3896896
|
||||
},
|
||||
{
|
||||
"updates": 50000,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 848,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3814948
|
||||
},
|
||||
{
|
||||
"updates": 100000,
|
||||
"visibleRasterizations": 0,
|
||||
"firstCellPixels": 638013437,
|
||||
"secondCellPixels": 395161943,
|
||||
"regular": 93,
|
||||
"combined": 0,
|
||||
"empty": 1696,
|
||||
"pages": 1,
|
||||
"glyphs": 93,
|
||||
"layoutVersion": 0,
|
||||
"shared": true,
|
||||
"preserved": true,
|
||||
"heap": 3678164
|
||||
}
|
||||
],
|
||||
"checks": {
|
||||
"rasterizations": 0,
|
||||
"emptyAfterClear": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user