diff --git a/src/vs/editor/browser/view.ts b/src/vs/editor/browser/view.ts index cef27e15410..9c0fa99f047 100644 --- a/src/vs/editor/browser/view.ts +++ b/src/vs/editor/browser/view.ts @@ -62,6 +62,7 @@ import { IVisibleRangeProvider, TextAreaEditContext } from './controller/editCon import { NativeEditContext } from './controller/editContext/native/nativeEditContext.js'; import { RulersGpu } from './viewParts/rulersGpu/rulersGpu.js'; import { EditContext } from './controller/editContext/native/editContextFactory.js'; +import { GpuMarkOverlay } from './viewParts/gpuMark/gpuMark.js'; export interface IContentWidgetData { @@ -194,6 +195,9 @@ export class View extends ViewEventHandler { marginViewOverlays.addDynamicOverlay(new MarginViewLineDecorationsOverlay(this._context)); marginViewOverlays.addDynamicOverlay(new LinesDecorationsOverlay(this._context)); marginViewOverlays.addDynamicOverlay(new LineNumbersOverlay(this._context)); + if (this._viewGpuContext) { + marginViewOverlays.addDynamicOverlay(new GpuMarkOverlay(this._context)); + } // Glyph margin widgets this._glyphMarginWidgets = new GlyphMarginWidgets(this._context); diff --git a/src/vs/editor/browser/viewParts/gpuMark/gpuMark.css b/src/vs/editor/browser/viewParts/gpuMark/gpuMark.css new file mode 100644 index 00000000000..0aa4397ea7e --- /dev/null +++ b/src/vs/editor/browser/viewParts/gpuMark/gpuMark.css @@ -0,0 +1,14 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +.monaco-editor .margin-view-overlays .gpu-mark { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 2px; + display: inline-block; + background: var(--vscode-editorLineNumber-foreground); +} diff --git a/src/vs/editor/browser/viewParts/gpuMark/gpuMark.ts b/src/vs/editor/browser/viewParts/gpuMark/gpuMark.ts new file mode 100644 index 00000000000..e1d25ac2794 --- /dev/null +++ b/src/vs/editor/browser/viewParts/gpuMark/gpuMark.ts @@ -0,0 +1,97 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as viewEvents from '../../../common/viewEvents.js'; +import { ViewContext } from '../../../common/viewModel/viewContext.js'; +import { ViewGpuContext } from '../../gpu/viewGpuContext.js'; +import { DynamicViewOverlay } from '../../view/dynamicViewOverlay.js'; +import { RenderingContext } from '../../view/renderingContext.js'; +import { ViewLineOptions } from '../viewLines/viewLineOptions.js'; +import './gpuMark.css'; + +/** + * A mark on lines to make identification of GPU-rendered lines vs DOM easier. + */ +export class GpuMarkOverlay extends DynamicViewOverlay { + + public static readonly CLASS_NAME = 'gpu-mark'; + + private readonly _context: ViewContext; + + private _renderResult: string[] | null; + + constructor(context: ViewContext) { + super(); + this._context = context; + this._renderResult = null; + this._context.addEventHandler(this); + } + + public override dispose(): void { + this._context.removeEventHandler(this); + this._renderResult = null; + super.dispose(); + } + + // --- begin event handlers + + public override onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean { + return true; + } + public override onCursorStateChanged(e: viewEvents.ViewCursorStateChangedEvent): boolean { + return true; + } + public override onFlushed(e: viewEvents.ViewFlushedEvent): boolean { + return true; + } + public override onLinesChanged(e: viewEvents.ViewLinesChangedEvent): boolean { + return true; + } + public override onLinesDeleted(e: viewEvents.ViewLinesDeletedEvent): boolean { + return true; + } + public override onLinesInserted(e: viewEvents.ViewLinesInsertedEvent): boolean { + return true; + } + public override onScrollChanged(e: viewEvents.ViewScrollChangedEvent): boolean { + return e.scrollTopChanged; + } + public override onZonesChanged(e: viewEvents.ViewZonesChangedEvent): boolean { + return true; + } + public override onDecorationsChanged(e: viewEvents.ViewDecorationsChangedEvent): boolean { + return true; + } + + // --- end event handlers + + public prepareRender(ctx: RenderingContext): void { + const visibleStartLineNumber = ctx.visibleRange.startLineNumber; + const visibleEndLineNumber = ctx.visibleRange.endLineNumber; + + const viewportData = ctx.viewportData; + const options = new ViewLineOptions(this._context.configuration, this._context.theme.type); + + const output: string[] = []; + for (let lineNumber = visibleStartLineNumber; lineNumber <= visibleEndLineNumber; lineNumber++) { + const lineIndex = lineNumber - visibleStartLineNumber; + const canRender = ViewGpuContext.canRender(options, viewportData, lineNumber); + output[lineIndex] = canRender ? `
` : ''; + } + + this._renderResult = output; + } + + public render(startLineNumber: number, lineNumber: number): string { + if (!this._renderResult) { + return ''; + } + const lineIndex = lineNumber - startLineNumber; + if (lineIndex < 0 || lineIndex >= this._renderResult.length) { + return ''; + } + return this._renderResult[lineIndex]; + } +}