Skip to content

Commit

Permalink
Merge pull request #4142 from Tyriar/defer_paused_resize
Browse files Browse the repository at this point in the history
Defer paused renderer resize to idle callback
  • Loading branch information
Tyriar authored Sep 24, 2022
2 parents 275a8a9 + aec1f2b commit a9eea3f
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 7 deletions.
2 changes: 1 addition & 1 deletion addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { tryDrawCustomChar } from 'browser/renderer/CustomGlyphs';
import { excludeFromContrastRatioDemands, isPowerlineGlyph, isRestrictedPowerlineGlyph } from 'browser/renderer/RendererUtils';
import { IUnicodeService } from 'common/services/Services';
import { FourKeyMap } from 'common/MultiKeyMap';
import { IdleTaskQueue } from 'common/IdleTaskQueue';
import { IdleTaskQueue } from 'common/Idle';

// For debugging purposes, it can be useful to set this to a really tiny value,
// to verify that LRU eviction works.
Expand Down
9 changes: 8 additions & 1 deletion src/browser/services/RenderService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { addDisposableDomListener } from 'browser/Lifecycle';
import { IColorSet, IRenderDebouncerWithCallback } from 'browser/Types';
import { IOptionsService, IBufferService, IDecorationService } from 'common/services/Services';
import { ICharSizeService, ICoreBrowserService, IRenderService } from 'browser/services/Services';
import { DebouncedIdleTask } from 'common/Idle';

interface ISelectionState {
start: [number, number] | undefined;
Expand All @@ -24,6 +25,7 @@ export class RenderService extends Disposable implements IRenderService {

private _renderDebouncer: IRenderDebouncerWithCallback;
private _screenDprMonitor: ScreenDprMonitor;
private _pausedResizeTask = new DebouncedIdleTask();

private _isPaused: boolean = false;
private _needsFullRefresh: boolean = false;
Expand Down Expand Up @@ -105,6 +107,7 @@ export class RenderService extends Disposable implements IRenderService {
}

if (!this._isPaused && this._needsFullRefresh) {
this._pausedResizeTask.flush();
this.refreshRows(0, this._rowCount - 1);
this._needsFullRefresh = false;
}
Expand Down Expand Up @@ -204,7 +207,11 @@ export class RenderService extends Disposable implements IRenderService {
}

public onResize(cols: number, rows: number): void {
this._renderer.onResize(cols, rows);
if (this._isPaused) {
this._pausedResizeTask.set(() => this._renderer.onResize(cols, rows));
} else {
this._renderer.onResize(cols, rows);
}
this._fullRefresh();
}

Expand Down
50 changes: 45 additions & 5 deletions src/common/IdleTaskQueue.ts → src/common/Idle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* and care should be taken to ensure they're non-urgent and will not introduce race conditions.
*/
export class IdleTaskQueue {
private _tasks: Function[] = [];
private _tasks: (() => void)[] = [];
private _idleCallback?: number;
private _maxTaskDuration: number;
private _i = 0;
Expand All @@ -24,11 +24,33 @@ export class IdleTaskQueue {
/**
* Adds a task to the queue which will run in a future idle callback.
*/
public enqueue(task: Function): void {
public enqueue(task: () => void): void {
this._tasks.push(task);
this._start();
}

/**
* Flushes the queue, running all remaining tasks synchronously.
*/
public flush(): void {
while (this._i < this._tasks.length) {
this._tasks[this._i++]();
}
this.clear();
}

/**
* Clears any remaining tasks from the queue, these will not be run.
*/
public clear(): void {
if (this._idleCallback) {
cancelIdleCallback(this._idleCallback);
this._idleCallback = undefined;
}
this._i = 0;
this._tasks.length = 0;
}

private _start(): void {
if (!this._idleCallback) {
this._idleCallback = requestIdleCallback(() => this._process());
Expand All @@ -45,8 +67,26 @@ export class IdleTaskQueue {
return;
}
}
// Clear the queue
this._i = 0;
this._tasks.length = 0;
this.clear();
}
}

export class DebouncedIdleTask {
private _queue: IdleTaskQueue;

/**
* @param targetFps The target frame rate.
*/
constructor(targetFps: number = 240) {
this._queue = new IdleTaskQueue(targetFps);
}

public set(task: () => void): void {
this._queue.clear();
this._queue.enqueue(task);
}

public flush(): void {
this._queue.flush();
}
}

0 comments on commit a9eea3f

Please sign in to comment.