From aef2733ea8111c49cd543d4f1e315537e3bbbaf3 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 16 Aug 2024 06:27:45 -0700 Subject: [PATCH] Only copy used parts of texture atlas This will slow as the page gets filled but this simple change improves start up quite a bit --- src/vs/editor/browser/view/gpu/atlas/atlas.ts | 1 + .../editor/browser/view/gpu/atlas/textureAtlasPage.ts | 10 +++++++++- src/vs/editor/browser/view/gpu/gpuViewLayer.ts | 5 ++--- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/browser/view/gpu/atlas/atlas.ts b/src/vs/editor/browser/view/gpu/atlas/atlas.ts index 3ac74d5bfc9ac..51b15e6c1d9f1 100644 --- a/src/vs/editor/browser/view/gpu/atlas/atlas.ts +++ b/src/vs/editor/browser/view/gpu/atlas/atlas.ts @@ -39,6 +39,7 @@ export interface ITextureAtlasAllocator { export interface IReadableTextureAtlasPage { readonly version: number; + readonly usedArea: Readonly; readonly glyphs: IterableIterator; readonly source: OffscreenCanvas; getUsagePreview(): Promise; diff --git a/src/vs/editor/browser/view/gpu/atlas/textureAtlasPage.ts b/src/vs/editor/browser/view/gpu/atlas/textureAtlasPage.ts index 2bada51266de4..a78fc546edbce 100644 --- a/src/vs/editor/browser/view/gpu/atlas/textureAtlasPage.ts +++ b/src/vs/editor/browser/view/gpu/atlas/textureAtlasPage.ts @@ -6,7 +6,7 @@ import { Event } from 'vs/base/common/event'; import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { TwoKeyMap } from 'vs/base/common/map'; -import type { IReadableTextureAtlasPage, ITextureAtlasAllocator, ITextureAtlasGlyph } from 'vs/editor/browser/view/gpu/atlas/atlas'; +import type { IBoundingBox, IReadableTextureAtlasPage, ITextureAtlasAllocator, ITextureAtlasGlyph } from 'vs/editor/browser/view/gpu/atlas/atlas'; import { TextureAtlasShelfAllocator } from 'vs/editor/browser/view/gpu/atlas/textureAtlasShelfAllocator'; import { TextureAtlasSlabAllocator } from 'vs/editor/browser/view/gpu/atlas/textureAtlasSlabAllocator'; import type { GlyphRasterizer } from 'vs/editor/browser/view/gpu/raster/glyphRasterizer'; @@ -16,6 +16,11 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; export class TextureAtlasPage extends Disposable implements IReadableTextureAtlasPage { private _version: number = 0; + private _usedArea: IBoundingBox = { left: 0, top: 0, right: 0, bottom: 0 }; + public get usedArea(): Readonly { + return this._usedArea; + } + /** * The version of the texture atlas. This is incremented every time the page's texture changes. */ @@ -82,7 +87,10 @@ export class TextureAtlasPage extends Disposable implements IReadableTextureAtla const glyph = this._allocator.allocate(chars, tokenFg, rasterizedGlyph)!; this._glyphMap.set(chars, tokenFg, glyph); this._glyphInOrderSet.add(glyph); + this._version++; + this._usedArea.right = Math.max(this._usedArea.right, glyph.x + glyph.w); + this._usedArea.bottom = Math.max(this._usedArea.bottom, glyph.y + glyph.h); if (this._logService.getLevel() === LogLevel.Trace) { this._logService.trace('New glyph', { diff --git a/src/vs/editor/browser/view/gpu/gpuViewLayer.ts b/src/vs/editor/browser/view/gpu/gpuViewLayer.ts index 9933c3fea2d14..b3fbe758e7167 100644 --- a/src/vs/editor/browser/view/gpu/gpuViewLayer.ts +++ b/src/vs/editor/browser/view/gpu/gpuViewLayer.ts @@ -326,11 +326,10 @@ export class GpuViewLayerRenderer { entryOffset += SpriteInfoStorageBufferInfo.Size; } this._device.queue.writeBuffer(this._glyphStorageBuffer[layerIndex], 0, values); - // TODO: Draw only dirty regions this._device.queue.copyExternalImageToTexture( { source: page.source }, - { texture: this._atlasGpuTexture, origin: { x: 0, y: 0, z: layerIndex } }, - { width: page.source.width, height: page.source.height }, + { texture: this._atlasGpuTexture, origin: { x: page.usedArea.left, y: page.usedArea.top, z: layerIndex } }, + { width: page.usedArea.right - page.usedArea.left, height: page.usedArea.bottom - page.usedArea.top }, ); this._atlasGpuTextureVersions[layerIndex] = page.version; }