From 8a0122f482a2c9a63dcb535be8d9f29e596e1e5f Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 12 Nov 2019 09:42:55 -0800 Subject: [PATCH] Add contrast caching to webgl --- .../src/atlas/CharAtlasUtils.ts | 2 +- .../src/atlas/WebglCharAtlas.ts | 27 ++++++++++++++----- src/browser/ColorContrastCache.ts | 6 ++--- src/browser/Types.d.ts | 4 +-- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/addons/xterm-addon-webgl/src/atlas/CharAtlasUtils.ts b/addons/xterm-addon-webgl/src/atlas/CharAtlasUtils.ts index ad25bf87c..8e26b1d6a 100644 --- a/addons/xterm-addon-webgl/src/atlas/CharAtlasUtils.ts +++ b/addons/xterm-addon-webgl/src/atlas/CharAtlasUtils.ts @@ -25,7 +25,7 @@ export function generateConfig(scaledCharWidth: number, scaledCharHeight: number // For the static char atlas, we only use the first 16 colors, but we need all 256 for the // dynamic character atlas. ansi: colors.ansi.slice(), - contrastCache: {} as any + contrastCache: colors.contrastCache }; return { devicePixelRatio: window.devicePixelRatio, diff --git a/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts b/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts index 1642ce088..b40c27cc9 100644 --- a/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts +++ b/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts @@ -207,8 +207,8 @@ export class WebglCharAtlas implements IDisposable { } } - private _getForegroundCss(bgColorMode: number, bgColor: number, fgColorMode: number, fgColor: number, inverse: boolean, bold: boolean): string { - const minimumContrastCss = this._getMinimumContrastCss(bgColorMode, bgColor, fgColorMode, fgColor, inverse, bold); + private _getForegroundCss(bg: number, bgColorMode: number, bgColor: number, fg: number, fgColorMode: number, fgColor: number, inverse: boolean, bold: boolean): string { + const minimumContrastCss = this._getMinimumContrastCss(bg, bgColorMode, bgColor, fg, fgColorMode, fgColor, inverse, bold); if (minimumContrastCss) { return minimumContrastCss; } @@ -267,21 +267,34 @@ export class WebglCharAtlas implements IDisposable { } } - private _getMinimumContrastCss(bgColorMode: number, bgColor: number, fgColorMode: number, fgColor: number, inverse: boolean, bold: boolean): string | undefined { - const bgRgba = this._resolveBackgroundRgba(bgColorMode, bgColor, fgColorMode, fgColor, inverse); - const fgRgba = this._resolveForegroundRgba(bgColorMode, bgColor, fgColorMode, fgColor, inverse, bold); + private _getMinimumContrastCss(bg: number, bgColorMode: number, bgColor: number, fg: number, fgColorMode: number, fgColor: number, inverse: boolean, bold: boolean): string | undefined { if (this._config.minimumContrastRatio === 1) { return undefined; } + + // Try get from cache first + const adjustedColor = this._config.colors.contrastCache.getCss(bg, fg); + if (adjustedColor !== undefined) { + return adjustedColor || undefined; + } + + const bgRgba = this._resolveBackgroundRgba(bgColorMode, bgColor, fgColorMode, fgColor, inverse); + const fgRgba = this._resolveForegroundRgba(bgColorMode, bgColor, fgColorMode, fgColor, inverse, bold); const result = ensureContrastRatioRgba(bgRgba, fgRgba, this._config.minimumContrastRatio); + if (!result) { + this._config.colors.contrastCache.setCss(bg, fg, null); return undefined; } - return toCss( + + const css = toCss( (result >> 24) & 0xFF, (result >> 16) & 0xFF, (result >> 8) & 0xFF ); + this._config.colors.contrastCache.setCss(bg, fg, css); + + return css; } private _drawToCache(code: number, bg: number, fg: number): IRasterizedGlyph; @@ -327,7 +340,7 @@ export class WebglCharAtlas implements IDisposable { `${fontStyle} ${fontWeight} ${this._config.fontSize * this._config.devicePixelRatio}px ${this._config.fontFamily}`; this._tmpCtx.textBaseline = 'top'; - this._tmpCtx.fillStyle = this._getForegroundCss(bgColorMode, bgColor, fgColorMode, fgColor, inverse, bold); + this._tmpCtx.fillStyle = this._getForegroundCss(bg, bgColorMode, bgColor, fg, fgColorMode, fgColor, inverse, bold); // Apply alpha to dim the character if (dim) { diff --git a/src/browser/ColorContrastCache.ts b/src/browser/ColorContrastCache.ts index 3198ad832..b96b66cc4 100644 --- a/src/browser/ColorContrastCache.ts +++ b/src/browser/ColorContrastCache.ts @@ -7,21 +7,21 @@ import { IColor, IColorContrastCache } from 'browser/Types'; export class ColorContrastCache implements IColorContrastCache { private _color: { [bg: number]: { [fg: number]: IColor | null | undefined } | undefined } = {}; - private _rgba: { [bg: number]: { [fg: number]: number | null | undefined } | undefined } = {}; + private _rgba: { [bg: number]: { [fg: number]: string | null | undefined } | undefined } = {}; public clear(): void { this._color = {}; this._rgba = {}; } - public setRgba(bg: number, fg: number, value: number | null): void { + public setCss(bg: number, fg: number, value: string | null): void { if (!this._rgba[bg]) { this._rgba[bg] = {}; } this._rgba[bg]![fg] = value; } - public getRgba(bg: number, fg: number): number | null | undefined { + public getCss(bg: number, fg: number): string | null | undefined { return this._rgba[bg] ? this._rgba[bg]![fg] : undefined; } diff --git a/src/browser/Types.d.ts b/src/browser/Types.d.ts index 06c3fe387..89c72fa3c 100644 --- a/src/browser/Types.d.ts +++ b/src/browser/Types.d.ts @@ -30,8 +30,8 @@ export interface IColorSet { export interface IColorContrastCache { clear(): void; - setRgba(bg: number, fg: number, value: number | null): void; - getRgba(bg: number, fg: number): number | null | undefined; + setCss(bg: number, fg: number, value: string | null): void; + getCss(bg: number, fg: number): string | null | undefined; setColor(bg: number, fg: number, value: IColor | null): void; getColor(bg: number, fg: number): IColor | null | undefined; }