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

Clear and commit all render data on view zones changed #234107

Merged
merged 2 commits into from
Nov 18, 2024
Merged
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
61 changes: 45 additions & 16 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 { ViewConfigurationChangedEvent, ViewLinesChangedEvent, ViewLinesDeletedEvent, ViewLinesInsertedEvent, ViewScrollChangedEvent, ViewTokensChangedEvent } from '../../common/viewEvents.js';
import { ViewEventType, type ViewConfigurationChangedEvent, type ViewLinesChangedEvent, type ViewLinesDeletedEvent, type ViewLinesInsertedEvent, type ViewScrollChangedEvent, type ViewTokensChangedEvent, type ViewZonesChangedEvent } 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 @@ -38,6 +38,8 @@ const enum CellBufferInfo {
TextureIndex = 5,
}

type QueuedBufferEvent = ViewLinesDeletedEvent | ViewZonesChangedEvent;

export class FullFileRenderStrategy extends ViewEventHandler implements IGpuRenderStrategy {

readonly wgsl: string = fullFileRenderStrategyWgsl;
Expand All @@ -61,7 +63,7 @@ export class FullFileRenderStrategy extends ViewEventHandler implements IGpuRend
private _scrollOffsetValueBuffer: Float32Array;
private _scrollInitialized: boolean = false;

private readonly _queuedBufferUpdates: [ViewLinesDeletedEvent[], ViewLinesDeletedEvent[]] = [[], []];
private readonly _queuedBufferUpdates: [QueuedBufferEvent[], QueuedBufferEvent[]] = [[], []];

get bindGroupEntries(): GPUBindGroupEntry[] {
return [
Expand Down Expand Up @@ -162,6 +164,18 @@ export class FullFileRenderStrategy extends ViewEventHandler implements IGpuRend
return true;
}

public override onZonesChanged(e: ViewZonesChangedEvent): boolean {
this._upToDateLines[0].clear();
this._upToDateLines[1].clear();

// 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;
}

// #endregion

private _invalidateLinesFrom(lineNumber: number): void {
Expand Down Expand Up @@ -230,19 +244,34 @@ export class FullFileRenderStrategy extends ViewEventHandler implements IGpuRend
while (queuedBufferUpdates.length) {
const e = queuedBufferUpdates.shift()!;

// Shift content below deleted line up
const deletedLineContentStartIndex = (e.fromLineNumber - 1) * this._viewGpuContext.maxGpuCols * Constants.IndicesPerCell;
const deletedLineContentEndIndex = (e.toLineNumber) * this._viewGpuContext.maxGpuCols * Constants.IndicesPerCell;
const nullContentStartIndex = (this._finalRenderedLine - (e.toLineNumber - e.fromLineNumber + 1)) * this._viewGpuContext.maxGpuCols * Constants.IndicesPerCell;
cellBuffer.set(cellBuffer.subarray(deletedLineContentEndIndex), deletedLineContentStartIndex);

// Zero out content on lines that are no longer valid
cellBuffer.fill(0, nullContentStartIndex);

// Update dirty lines and final rendered line
dirtyLineStart = Math.min(dirtyLineStart, e.fromLineNumber);
dirtyLineEnd = this._finalRenderedLine;
this._finalRenderedLine -= e.toLineNumber - e.fromLineNumber + 1;
switch (e.type) {
case ViewEventType.ViewLinesDeleted: {
// Shift content below deleted line up
const deletedLineContentStartIndex = (e.fromLineNumber - 1) * this._viewGpuContext.maxGpuCols * Constants.IndicesPerCell;
const deletedLineContentEndIndex = (e.toLineNumber) * this._viewGpuContext.maxGpuCols * Constants.IndicesPerCell;
const nullContentStartIndex = (this._finalRenderedLine - (e.toLineNumber - e.fromLineNumber + 1)) * this._viewGpuContext.maxGpuCols * Constants.IndicesPerCell;
cellBuffer.set(cellBuffer.subarray(deletedLineContentEndIndex), deletedLineContentStartIndex);

// Zero out content on lines that are no longer valid
cellBuffer.fill(0, nullContentStartIndex);

// Update dirty lines and final rendered line
dirtyLineStart = Math.min(dirtyLineStart, e.fromLineNumber);
dirtyLineEnd = this._finalRenderedLine;
this._finalRenderedLine -= e.toLineNumber - e.fromLineNumber + 1;
break;
}
case ViewEventType.ViewZonesChanged: {
// TODO: We could retain render data if we know what view zones changed and how
// Zero out content on all lines
cellBuffer.fill(0);

dirtyLineStart = 1;
dirtyLineEnd = this._finalRenderedLine;
this._finalRenderedLine = 0;
break;
}
}
}

for (y = viewportData.startLineNumber; y <= viewportData.endLineNumber; y++) {
Expand Down Expand Up @@ -360,7 +389,7 @@ export class FullFileRenderStrategy extends ViewEventHandler implements IGpuRend
);
}

private _queueBufferUpdate(e: ViewLinesDeletedEvent) {
private _queueBufferUpdate(e: QueuedBufferEvent) {
this._queuedBufferUpdates[0].push(e);
this._queuedBufferUpdates[1].push(e);
}
Expand Down
Loading