Only upload textures that change

This commit is contained in:
Daniel Imms
2022-10-29 13:27:33 -07:00
parent 0a49a5dde1
commit c257a7247e
4 changed files with 21 additions and 19 deletions
@@ -368,9 +368,9 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
this._ctx.save();
this._clipRow(y);
// Draw the image, use the bitmap if it's available
if (this._charAtlas.hasCanvasChanged) {
if (this._charAtlas.pages[0].hasCanvasChanged) {
this._bitmapGenerator?.refresh();
this._charAtlas.hasCanvasChanged = false;
this._charAtlas.pages[0].hasCanvasChanged = false;
}
this._ctx.drawImage(
this._bitmapGenerator?.bitmap || this._charAtlas!.pages[0].canvas,
@@ -335,14 +335,14 @@ export class GlyphRenderer extends Disposable {
gl.bindBuffer(gl.ARRAY_BUFFER, this._attributesBuffer);
gl.bufferData(gl.ARRAY_BUFFER, activeBuffer.subarray(0, bufferLength), gl.STREAM_DRAW);
// Bind the texture atlas if it's changed
if (this._atlas.hasCanvasChanged) {
this._atlas.hasCanvasChanged = false;
// TODO: Make nicer
const layerTextureUnits = new Int32Array([0, 1, 2, 3, 4, 5, 6, 7]);
gl.uniform1iv(this._textureLocation, layerTextureUnits);
// TODO: Only upload the texture(s) that changed
for (let i = 0; i < this._atlas.pages.length; i++) {
// TODO: Only do this once
const layerTextureUnits = new Int32Array([0, 1, 2, 3, 4, 5, 6, 7]);
gl.uniform1iv(this._textureLocation, layerTextureUnits);
// Bind the atlas page texture if they have changed
for (let i = 0; i < this._atlas.pages.length; i++) {
if (this._atlas.pages[i].hasCanvasChanged) {
this._atlas.pages[i].hasCanvasChanged = false;
gl.activeTexture(gl.TEXTURE0 + i);
gl.bindTexture(gl.TEXTURE_2D, this._atlasTextures[i]);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._atlas.pages[i].canvas);
+10 -6
View File
@@ -47,14 +47,12 @@ export class TextureAtlas implements ITextureAtlas {
// The texture that the atlas is drawn to
private _pages: AtlasPage[] = [];
public get pages(): { canvas: HTMLCanvasElement }[] { return this._pages; }
public get pages(): { canvas: HTMLCanvasElement, hasCanvasChanged: boolean }[] { return this._pages; }
private _tmpCanvas: HTMLCanvasElement;
// A temporary context that glyphs are drawn to before being transfered to the atlas.
private _tmpCtx: CanvasRenderingContext2D;
public hasCanvasChanged = false;
private _workBoundingBox: IBoundingBox = { top: 0, left: 0, bottom: 0, right: 0 };
private _workAttributeData: AttributeData = new AttributeData();
@@ -130,7 +128,6 @@ export class TextureAtlas implements ITextureAtlas {
this._cacheMap.clear();
this._cacheMapCombined.clear();
this._didWarmUp = false;
this.hasCanvasChanged = true;
}
public getRasterizedGlyphCombinedChar(chars: string, bg: number, fg: number, ext: number): IRasterizedGlyph {
@@ -317,8 +314,6 @@ export class TextureAtlas implements ITextureAtlas {
// Uncomment for debugging
// console.log(`draw to cache "${chars}"`, bg, fg, ext);
this.hasCanvasChanged = true;
// Allow 1 cell width per character, with a minimum of 2 (CJK), plus some padding. This is used
// to draw the glyph to the canvas as well as to restrict the bounding box search to ensure
// giant ligatures (eg. =====>) don't impact overall performance.
@@ -589,6 +584,8 @@ export class TextureAtlas implements ITextureAtlas {
}
const page = this._pages[this._pages.length - 1];
page.hasCanvasChanged = true;
const rasterizedGlyph = this._findGlyphBoundingBox(imageData, this._workBoundingBox, allowedWidth, restrictedPowerlineGlyph, customGlyph, padding, page.canvas.width, page.canvas.height);
// Find the best atlas row to use
@@ -761,6 +758,12 @@ class AtlasPage {
public readonly canvas: HTMLCanvasElement;
public readonly ctx: CanvasRenderingContext2D;
/**
* Whether the canvas of the atlas page has changed, this is only set to true by the atlas, the
* user of the boolean is required to reset its value to false.
*/
public hasCanvasChanged = false;
// Texture atlas current positioning data. The texture packing strategy used is to fill from
// left-to-right and top-to-bottom. When the glyph being written is less than half of the current
// row's height, the following happens:
@@ -796,6 +799,7 @@ class AtlasPage {
this.currentRow.y = 0;
this.currentRow.height = 0;
this.fixedRows.length = 0;
this.hasCanvasChanged = true;
}
}
+1 -3
View File
@@ -87,9 +87,7 @@ export interface IRenderer extends IDisposable {
}
export interface ITextureAtlas extends IDisposable {
readonly pages: { canvas: HTMLCanvasElement }[];
hasCanvasChanged: boolean;
readonly pages: { canvas: HTMLCanvasElement, hasCanvasChanged: boolean }[];
onAddTextureAtlasCanvas: IEvent<HTMLCanvasElement>;