Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache up to date lines and don't write them unless invalidated #233947

Merged
merged 1 commit into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 63 additions & 5 deletions src/vs/editor/browser/gpu/fullFileRenderStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { EditorOption } from '../../common/config/editorOptions.js';
import { CursorColumns } from '../../common/core/cursorColumns.js';
import type { IViewLineTokens } from '../../common/tokens/lineTokens.js';
import { ViewEventHandler } from '../../common/viewEventHandler.js';
import type { ViewLinesDeletedEvent, ViewScrollChangedEvent } from '../../common/viewEvents.js';
import type { ViewConfigurationChangedEvent, ViewLinesChangedEvent, ViewLinesDeletedEvent, ViewLinesInsertedEvent, ViewScrollChangedEvent, ViewTokensChangedEvent } from '../../common/viewEvents.js';
import type { ViewportData } from '../../common/viewLayout/viewLinesViewportData.js';
import type { ViewLineRenderingData } from '../../common/viewModel.js';
import type { ViewContext } from '../../common/viewModel/viewContext.js';
Expand Down Expand Up @@ -107,8 +107,66 @@ export class FullFileRenderStrategy extends ViewEventHandler implements IGpuRend

// #region Event handlers

public override onConfigurationChanged(e: ViewConfigurationChangedEvent): boolean {
this._upToDateLines[0].clear();
this._upToDateLines[1].clear();
return true;
}

public override onTokensChanged(e: ViewTokensChangedEvent): boolean {
// TODO: This currently fires for the entire viewport whenever scrolling stops
// https://github.com/microsoft/vscode/issues/233942
for (const range of e.ranges) {
for (let i = range.fromLineNumber; i <= range.toLineNumber; i++) {
this._upToDateLines[0].delete(i);
this._upToDateLines[1].delete(i);
}
}
return true;
}

public override onLinesDeleted(e: ViewLinesDeletedEvent): boolean {
// TODO: This currently invalidates everything after the deleted line, it could shift the
// line data up to retain some up to date lines
// TODO: This does not invalidate lines that are no longer in the file
for (const i of [0, 1]) {
const upToDateLines = this._upToDateLines[i];
const lines = Array.from(upToDateLines);
for (const upToDateLine of lines) {
if (upToDateLine > e.fromLineNumber) {
upToDateLines.delete(upToDateLine);
}
}
}

// Queue updates that need to happen on the active buffer, not just the cache. This is
// deferred since the active buffer could be locked by the GPU which would block the main
// thread.
this._queueBufferUpdate(e);

return true;
}

public override onLinesInserted(e: ViewLinesInsertedEvent): boolean {
// TODO: This currently invalidates everything after the deleted line, it could shift the
// line data up to retain some up to date lines
for (const i of [0, 1]) {
const upToDateLines = this._upToDateLines[i];
const lines = Array.from(upToDateLines);
for (const upToDateLine of lines) {
if (upToDateLine > e.fromLineNumber) {
upToDateLines.delete(upToDateLine);
}
}
}
return true;
}

public override onLinesChanged(e: ViewLinesChangedEvent): boolean {
for (let i = e.fromLineNumber; i < e.fromLineNumber + e.count; i++) {
this._upToDateLines[0].delete(i);
this._upToDateLines[1].delete(i);
}
return true;
}

Expand Down Expand Up @@ -201,10 +259,10 @@ export class FullFileRenderStrategy extends ViewEventHandler implements IGpuRend
continue;
}

// TODO: Update on dirty lines; is this known by line before rendering?
// if (upToDateLines.has(y)) {
// continue;
// }
// Skip updating the line if it's already up to date
if (upToDateLines.has(y)) {
continue;
}
dirtyLineStart = Math.min(dirtyLineStart, y);
dirtyLineEnd = Math.max(dirtyLineEnd, y);

Expand Down
9 changes: 7 additions & 2 deletions src/vs/editor/browser/gpu/gpu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import type { ViewLinesDeletedEvent } from '../../common/viewEvents.js';
import type { ViewConfigurationChangedEvent, ViewLinesChangedEvent, ViewLinesDeletedEvent, ViewLinesInsertedEvent, ViewScrollChangedEvent, ViewTokensChangedEvent } from '../../common/viewEvents.js';
import type { ViewportData } from '../../common/viewLayout/viewLinesViewportData.js';
import type { ViewLineOptions } from '../viewParts/viewLines/viewLineOptions.js';

Expand All @@ -22,7 +22,12 @@ export interface IGpuRenderStrategy {
readonly wgsl: string;
readonly bindGroupEntries: GPUBindGroupEntry[];

onLinesDeleted(e: ViewLinesDeletedEvent): void;
onLinesDeleted(e: ViewLinesDeletedEvent): boolean;
onConfigurationChanged(e: ViewConfigurationChangedEvent): boolean;
onTokensChanged(e: ViewTokensChangedEvent): boolean;
onLinesInserted(e: ViewLinesInsertedEvent): boolean;
onLinesChanged(e: ViewLinesChangedEvent): boolean;
onScrollChanged(e?: ViewScrollChangedEvent): boolean;

/**
* Resets the render strategy, clearing all data and setting up for a new frame.
Expand Down
5 changes: 1 addition & 4 deletions src/vs/editor/browser/viewParts/viewLinesGpu/viewLinesGpu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ export class ViewLinesGpu extends ViewPart implements IViewLines {
override onDecorationsChanged(e: viewEvents.ViewDecorationsChangedEvent): boolean { return true; }
override onFlushed(e: viewEvents.ViewFlushedEvent): boolean { return true; }
override onLinesChanged(e: viewEvents.ViewLinesChangedEvent): boolean { return true; }
override onLinesDeleted(e: viewEvents.ViewLinesDeletedEvent): boolean { return true; }
override onLinesInserted(e: viewEvents.ViewLinesInsertedEvent): boolean { return true; }
override onRevealRangeRequest(e: viewEvents.ViewRevealRangeRequestEvent): boolean { return true; }
override onScrollChanged(e: viewEvents.ViewScrollChangedEvent): boolean { return true; }
Expand All @@ -396,10 +397,6 @@ export class ViewLinesGpu extends ViewPart implements IViewLines {
this._contentLeftObs.set(this._context.configuration.options.get(EditorOption.layoutInfo).contentLeft, undefined);
return true;
}
override onLinesDeleted(e: viewEvents.ViewLinesDeletedEvent): boolean {
this._renderStrategy.onLinesDeleted(e);
return true;
}

// #endregion

Expand Down
Loading