mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
lazy cleanup on buffer
This commit is contained in:
Vendored
+1
@@ -206,6 +206,7 @@ export interface IBufferLine {
|
||||
deleteCells(pos: number, n: number, fill: ICellData, eraseAttr?: IAttributeData): void;
|
||||
replaceCells(start: number, end: number, fill: ICellData, eraseAttr?: IAttributeData, respectProtect?: boolean): void;
|
||||
resize(cols: number, fill: ICellData): boolean;
|
||||
cleanupMemory(): number;
|
||||
fill(fillCellData: ICellData, respectProtect?: boolean): void;
|
||||
copyFrom(line: IBufferLine): void;
|
||||
clone(): IBufferLine;
|
||||
|
||||
@@ -14,6 +14,7 @@ import { Marker } from 'common/buffer/Marker';
|
||||
import { IOptionsService, IBufferService } from 'common/services/Services';
|
||||
import { DEFAULT_CHARSET } from 'common/data/Charsets';
|
||||
import { ExtendedAttrs } from 'common/buffer/AttributeData';
|
||||
import { DebouncedIdleTask } from 'common/TaskQueue';
|
||||
|
||||
export const MAX_BUFFER_SIZE = 4294967295; // 2^32 - 1
|
||||
|
||||
@@ -151,6 +152,9 @@ export class Buffer implements IBuffer {
|
||||
// store reference to null cell with default attrs
|
||||
const nullCell = this.getNullCell(DEFAULT_ATTR_DATA);
|
||||
|
||||
// defer memory cleanup of bufferlines
|
||||
let needsCleanup = 0;
|
||||
|
||||
// Increase max length if needed before adjustments to allow space to fill
|
||||
// as required.
|
||||
const newMaxLength = this._getCorrectBufferLength(newRows);
|
||||
@@ -164,7 +168,7 @@ export class Buffer implements IBuffer {
|
||||
// Deal with columns increasing (reducing needs to happen after reflow)
|
||||
if (this._cols < newCols) {
|
||||
for (let i = 0; i < this.lines.length; i++) {
|
||||
this.lines.get(i)!.resize(newCols, nullCell);
|
||||
needsCleanup |= +this.lines.get(i)!.resize(newCols, nullCell);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,13 +247,34 @@ export class Buffer implements IBuffer {
|
||||
// Trim the end of the line off if cols shrunk
|
||||
if (this._cols > newCols) {
|
||||
for (let i = 0; i < this.lines.length; i++) {
|
||||
this.lines.get(i)!.resize(newCols, nullCell);
|
||||
needsCleanup |= +this.lines.get(i)!.resize(newCols, nullCell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._cols = newCols;
|
||||
this._rows = newRows;
|
||||
|
||||
if (needsCleanup) {
|
||||
this._memoryCleanupTask.set(() => this._cleanupMemory());
|
||||
} else {
|
||||
// FIXME: DebouncedIdleTask has no clear method?
|
||||
this._memoryCleanupTask.set(() => {});
|
||||
}
|
||||
}
|
||||
|
||||
private _memoryCleanupTask: DebouncedIdleTask = new DebouncedIdleTask();
|
||||
|
||||
private _cleanupMemory(): void {
|
||||
let counted = 0;
|
||||
for (let i = 0; i < this.lines.length; i++) {
|
||||
counted += this.lines.get(i)!.cleanupMemory();
|
||||
// throttle to 5k lines
|
||||
if (counted > 5000) {
|
||||
this._memoryCleanupTask.set(() => this._cleanupMemory());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private get _isReflowEnabled(): boolean {
|
||||
|
||||
@@ -347,7 +347,7 @@ export class BufferLine implements IBufferLine {
|
||||
*/
|
||||
public resize(cols: number, fillCellData: ICellData): boolean {
|
||||
if (cols === this.length) {
|
||||
return this._data.length * 4 < this._data.buffer.byteLength * CLEANUP_THRESHOLD;
|
||||
return this._data.length * 4 * CLEANUP_THRESHOLD < this._data.buffer.byteLength;
|
||||
}
|
||||
const uint32Cells = cols * CELL_SIZE;
|
||||
if (cols > this.length) {
|
||||
@@ -384,7 +384,7 @@ export class BufferLine implements IBufferLine {
|
||||
}
|
||||
}
|
||||
this.length = cols;
|
||||
return uint32Cells * 4 < this._data.buffer.byteLength * CLEANUP_THRESHOLD;
|
||||
return uint32Cells * 4 * CLEANUP_THRESHOLD < this._data.buffer.byteLength;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -393,8 +393,8 @@ export class BufferLine implements IBufferLine {
|
||||
* memory by a factor of CLEANUP_THRESHOLD.
|
||||
* Returns 0 or 1 indicating whether a cleanup happened.
|
||||
*/
|
||||
public cleanupBuffer(): number {
|
||||
if (this._data.length * 4 < this._data.buffer.byteLength * CLEANUP_THRESHOLD) {
|
||||
public cleanupMemory(): number {
|
||||
if (this._data.length * 4 * CLEANUP_THRESHOLD < this._data.buffer.byteLength) {
|
||||
const data = new Uint32Array(this._data.length);
|
||||
data.set(this._data);
|
||||
this._data = data;
|
||||
|
||||
Reference in New Issue
Block a user