diff --git a/addons/addon-webgl/src/GlyphRenderer.ts b/addons/addon-webgl/src/GlyphRenderer.ts index 46b8efeb9..1efde442e 100644 --- a/addons/addon-webgl/src/GlyphRenderer.ts +++ b/addons/addon-webgl/src/GlyphRenderer.ts @@ -9,7 +9,7 @@ import { Disposable, toDisposable } from 'common/Lifecycle'; import { Terminal } from '@xterm/xterm'; import { IRenderModel, IWebGL2RenderingContext, IWebGLVertexArrayObject, type IRasterizedGlyph, type ITextureAtlas } from './Types'; import { createProgram, GLTexture, PROJECTION_MATRIX } from './WebglUtils'; -import type { IOptionsService } from 'common/services/Services'; +import type { ILogService, IOptionsService } from 'common/services/Services'; import { allowRescaling, throwIfFalsy } from 'browser/renderer/shared/RendererUtils'; interface IVertices { @@ -114,7 +114,8 @@ export class GlyphRenderer extends Disposable { private readonly _terminal: Terminal, private readonly _gl: IWebGL2RenderingContext, private _dimensions: IRenderDimensions, - private readonly _optionsService: IOptionsService + private readonly _optionsService: IOptionsService, + private readonly _logService: ILogService ) { super(); @@ -127,7 +128,7 @@ export class GlyphRenderer extends Disposable { TextureAtlas.maxTextureSize = throwIfFalsy(gl.getParameter(gl.MAX_TEXTURE_SIZE) as number | null); } - this._program = throwIfFalsy(createProgram(gl, vertexShaderSource, createFragmentShaderSource(TextureAtlas.maxAtlasPages))); + this._program = throwIfFalsy(createProgram(gl, vertexShaderSource, createFragmentShaderSource(TextureAtlas.maxAtlasPages), this._logService)); this._register(toDisposable(() => gl.deleteProgram(this._program))); // Uniform locations diff --git a/addons/addon-webgl/src/RectangleRenderer.ts b/addons/addon-webgl/src/RectangleRenderer.ts index 81e129e5c..6da92be13 100644 --- a/addons/addon-webgl/src/RectangleRenderer.ts +++ b/addons/addon-webgl/src/RectangleRenderer.ts @@ -14,6 +14,7 @@ import { RenderModelConstants } from './RenderModel'; import { IRenderModel, IWebGL2RenderingContext, IWebGLVertexArrayObject } from './Types'; import { createProgram, expandFloat32Array, PROJECTION_MATRIX } from './WebglUtils'; import { throwIfFalsy } from 'browser/renderer/shared/RendererUtils'; +import type { ILogService } from 'common/services/Services'; const enum VertexAttribLocations { POSITION = 0, @@ -89,13 +90,14 @@ export class RectangleRenderer extends Disposable { private _terminal: Terminal, private _gl: IWebGL2RenderingContext, private _dimensions: IRenderDimensions, - private readonly _themeService: IThemeService + private readonly _themeService: IThemeService, + private readonly _logService: ILogService ) { super(); const gl = this._gl; - this._program = throwIfFalsy(createProgram(gl, vertexShaderSource, fragmentShaderSource)); + this._program = throwIfFalsy(createProgram(gl, vertexShaderSource, fragmentShaderSource, this._logService)); this._register(toDisposable(() => gl.deleteProgram(this._program))); // Uniform locations diff --git a/addons/addon-webgl/src/TextureAtlas.ts b/addons/addon-webgl/src/TextureAtlas.ts index 34188235c..ba7db27d3 100644 --- a/addons/addon-webgl/src/TextureAtlas.ts +++ b/addons/addon-webgl/src/TextureAtlas.ts @@ -529,7 +529,7 @@ export class TextureAtlas implements ITextureAtlas { let customGlyph = false; if (this._config.customGlyphs !== false) { const variantOffset = this._workAttributeData.getUnderlineVariantOffset(); - customGlyph = tryDrawCustomGlyph(this._tmpCtx, chars, padding, padding, this._config.deviceCellWidth, this._config.deviceCellHeight, this._config.deviceCharWidth, this._config.deviceCharHeight, this._config.fontSize, this._config.devicePixelRatio, backgroundColor.css, variantOffset); + customGlyph = tryDrawCustomGlyph(this._tmpCtx, chars, padding, padding, this._config.deviceCellWidth, this._config.deviceCellHeight, this._config.deviceCharWidth, this._config.deviceCharHeight, this._config.fontSize, this._config.devicePixelRatio, this._logService, backgroundColor.css, variantOffset); } // Whether to clear pixels based on a threshold difference between the glyph color and the diff --git a/addons/addon-webgl/src/WebglAddon.ts b/addons/addon-webgl/src/WebglAddon.ts index f21fb704e..624c9ea38 100644 --- a/addons/addon-webgl/src/WebglAddon.ts +++ b/addons/addon-webgl/src/WebglAddon.ts @@ -9,7 +9,7 @@ import { ICharacterJoinerService, ICharSizeService, ICoreBrowserService, IRender import { ITerminal } from 'browser/Types'; import { Disposable, toDisposable } from 'common/Lifecycle'; import { getSafariVersion, isSafari } from 'common/Platform'; -import { ICoreService, IDecorationService, IOptionsService } from 'common/services/Services'; +import { ICoreService, IDecorationService, ILogService, IOptionsService } from 'common/services/Services'; import { IWebGL2RenderingContext } from './Types'; import { WebglRenderer } from './WebglRenderer'; import { Emitter, EventUtils } from 'common/Event'; @@ -65,6 +65,7 @@ export class WebglAddon extends Disposable implements ITerminalAddon, IWebglApi const charSizeService: ICharSizeService = unsafeCore._charSizeService; const coreBrowserService: ICoreBrowserService = unsafeCore._coreBrowserService; const decorationService: IDecorationService = unsafeCore._decorationService; + const logService: ILogService = unsafeCore._logService; const themeService: IThemeService = unsafeCore._themeService; this._renderer = this._register(new WebglRenderer( @@ -74,6 +75,7 @@ export class WebglAddon extends Disposable implements ITerminalAddon, IWebglApi coreBrowserService, coreService, decorationService, + logService, optionsService, themeService, this._customGlyphs, diff --git a/addons/addon-webgl/src/WebglRenderer.ts b/addons/addon-webgl/src/WebglRenderer.ts index 500308bd1..2c20accc7 100644 --- a/addons/addon-webgl/src/WebglRenderer.ts +++ b/addons/addon-webgl/src/WebglRenderer.ts @@ -15,7 +15,7 @@ import { AttributeData } from 'common/buffer/AttributeData'; import { CellData } from 'common/buffer/CellData'; import { Attributes, Content, FgFlags, NULL_CELL_CHAR, NULL_CELL_CODE } from 'common/buffer/Constants'; import { TextBlinkStateManager } from 'browser/renderer/shared/TextBlinkStateManager'; -import { ICoreService, IDecorationService, IOptionsService } from 'common/services/Services'; +import { ICoreService, IDecorationService, ILogService, IOptionsService } from 'common/services/Services'; import { Terminal } from '@xterm/xterm'; import { GlyphRenderer } from './GlyphRenderer'; import { RectangleRenderer } from './RectangleRenderer'; @@ -77,6 +77,7 @@ export class WebglRenderer extends Disposable implements IRenderer { private readonly _coreBrowserService: ICoreBrowserService, private readonly _coreService: ICoreService, private readonly _decorationService: IDecorationService, + private readonly _logService: ILogService, private readonly _optionsService: IOptionsService, private readonly _themeService: IThemeService, private readonly _customGlyphs: boolean = true, @@ -122,19 +123,19 @@ export class WebglRenderer extends Disposable implements IRenderer { this._deviceMaxTextureSize = this._gl.getParameter(this._gl.MAX_TEXTURE_SIZE); this._register(addDisposableListener(this._canvas, 'webglcontextlost', (e) => { - console.log('webglcontextlost event received'); + this._logService.debug('webglcontextlost event received'); // Prevent the default behavior in order to enable WebGL context restoration. e.preventDefault(); // Wait a few seconds to see if the 'webglcontextrestored' event is fired. // If not, dispatch the onContextLoss notification to observers. this._contextRestorationTimeout = setTimeout(() => { this._contextRestorationTimeout = undefined; - console.warn('webgl context not restored; firing onContextLoss'); + this._logService.warn('webgl context not restored; firing onContextLoss'); this._onContextLoss.fire(e); }, 3000 /* ms */); })); this._register(addDisposableListener(this._canvas, 'webglcontextrestored', (e) => { - console.warn('webglcontextrestored event received'); + this._logService.warn('webglcontextrestored event received'); clearTimeout(this._contextRestorationTimeout); this._contextRestorationTimeout = undefined; // The texture atlas and glyph renderer must be fully reinitialized @@ -274,8 +275,8 @@ export class WebglRenderer extends Disposable implements IRenderer { * Initializes members dependent on WebGL context state. */ private _initializeWebGLState(): [RectangleRenderer, GlyphRenderer] { - this._rectangleRenderer.value = new RectangleRenderer(this._terminal, this._gl, this.dimensions, this._themeService); - this._glyphRenderer.value = new GlyphRenderer(this._terminal, this._gl, this.dimensions, this._optionsService); + this._rectangleRenderer.value = new RectangleRenderer(this._terminal, this._gl, this.dimensions, this._themeService, this._logService); + this._glyphRenderer.value = new GlyphRenderer(this._terminal, this._gl, this.dimensions, this._optionsService, this._logService); // Update dimensions and acquire char atlas this.handleCharSizeChanged(); diff --git a/addons/addon-webgl/src/WebglUtils.ts b/addons/addon-webgl/src/WebglUtils.ts index da765c802..9944c6bd3 100644 --- a/addons/addon-webgl/src/WebglUtils.ts +++ b/addons/addon-webgl/src/WebglUtils.ts @@ -4,6 +4,7 @@ */ import { throwIfFalsy } from 'browser/renderer/shared/RendererUtils'; +import type { ILogService } from 'common/services/Services'; /** * A matrix that when multiplies will translate 0-1 coordinates (left to right, @@ -16,21 +17,21 @@ export const PROJECTION_MATRIX = new Float32Array([ -1, 1, 0, 1 ]); -export function createProgram(gl: WebGLRenderingContext, vertexSource: string, fragmentSource: string): WebGLProgram | undefined { +export function createProgram(gl: WebGLRenderingContext, vertexSource: string, fragmentSource: string, logService: ILogService): WebGLProgram | undefined { const program = throwIfFalsy(gl.createProgram()); - gl.attachShader(program, throwIfFalsy(createShader(gl, gl.VERTEX_SHADER, vertexSource))); - gl.attachShader(program, throwIfFalsy(createShader(gl, gl.FRAGMENT_SHADER, fragmentSource))); + gl.attachShader(program, throwIfFalsy(createShader(gl, gl.VERTEX_SHADER, vertexSource, logService))); + gl.attachShader(program, throwIfFalsy(createShader(gl, gl.FRAGMENT_SHADER, fragmentSource, logService))); gl.linkProgram(program); const success = gl.getProgramParameter(program, gl.LINK_STATUS); if (success) { return program; } - console.error(gl.getProgramInfoLog(program)); + logService.error(gl.getProgramInfoLog(program)); gl.deleteProgram(program); } -export function createShader(gl: WebGLRenderingContext, type: number, source: string): WebGLShader | undefined { +export function createShader(gl: WebGLRenderingContext, type: number, source: string, logService: ILogService): WebGLShader | undefined { const shader = throwIfFalsy(gl.createShader(type)); gl.shaderSource(shader, source); gl.compileShader(shader); @@ -39,7 +40,7 @@ export function createShader(gl: WebGLRenderingContext, type: number, source: st return shader; } - console.error(gl.getShaderInfoLog(shader)); + logService.error(gl.getShaderInfoLog(shader)); gl.deleteShader(shader); } diff --git a/addons/addon-webgl/src/customGlyphs/CustomGlyphRasterizer.ts b/addons/addon-webgl/src/customGlyphs/CustomGlyphRasterizer.ts index ba8925727..357d512d2 100644 --- a/addons/addon-webgl/src/customGlyphs/CustomGlyphRasterizer.ts +++ b/addons/addon-webgl/src/customGlyphs/CustomGlyphRasterizer.ts @@ -4,6 +4,7 @@ */ import { throwIfFalsy } from 'browser/renderer/shared/RendererUtils'; +import type { ILogService } from 'common/services/Services'; import { customGlyphDefinitions } from './CustomGlyphDefinitions'; import { CustomGlyphDefinitionType, CustomGlyphScaleType, CustomGlyphVectorType, type CustomGlyphDefinitionPart, type CustomGlyphPathDrawFunctionDefinition, type CustomGlyphPatternDefinition, type ICustomGlyphSolidOctantBlockVector, type ICustomGlyphVectorShape } from './Types'; @@ -22,6 +23,7 @@ export function tryDrawCustomGlyph( deviceCharHeight: number, fontSize: number, devicePixelRatio: number, + logService: ILogService, backgroundColor?: string, variantOffset: number = 0 ): boolean { @@ -30,7 +32,7 @@ export function tryDrawCustomGlyph( // Normalize to array for uniform handling const parts = Array.isArray(unifiedCharDefinition) ? unifiedCharDefinition : [unifiedCharDefinition]; for (const part of parts) { - drawDefinitionPart(ctx, part, xOffset, yOffset, deviceCellWidth, deviceCellHeight, deviceCharWidth, deviceCharHeight, fontSize, devicePixelRatio, backgroundColor, variantOffset); + drawDefinitionPart(ctx, part, xOffset, yOffset, deviceCellWidth, deviceCellHeight, deviceCharWidth, deviceCharHeight, fontSize, devicePixelRatio, logService, backgroundColor, variantOffset); } return true; } @@ -49,6 +51,7 @@ function drawDefinitionPart( deviceCharHeight: number, fontSize: number, devicePixelRatio: number, + logService: ILogService, backgroundColor?: string, variantOffset: number = 0 ): void { @@ -79,7 +82,7 @@ function drawDefinitionPart( drawPatternChar(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight, variantOffset); break; case CustomGlyphDefinitionType.PATH_FUNCTION: - drawPathFunctionCharacter(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight, devicePixelRatio, part.strokeWidth); + drawPathFunctionCharacter(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight, devicePixelRatio, logService, part.strokeWidth); break; case CustomGlyphDefinitionType.PATH: drawPathDefinitionCharacter(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight, devicePixelRatio, part.strokeWidth); @@ -88,7 +91,7 @@ function drawDefinitionPart( drawPathNegativeDefinitionCharacter(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight, devicePixelRatio, backgroundColor); break; case CustomGlyphDefinitionType.VECTOR_SHAPE: - drawVectorShape(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight, fontSize, devicePixelRatio); + drawVectorShape(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight, fontSize, devicePixelRatio, logService); break; case CustomGlyphDefinitionType.BRAILLE: drawBrailleCharacter(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight); @@ -510,6 +513,7 @@ function drawPathFunctionCharacter( deviceCellWidth: number, deviceCellHeight: number, devicePixelRatio: number, + logService: ILogService, strokeWidth?: number ): void { ctx.save(); @@ -536,7 +540,7 @@ function drawPathFunctionCharacter( } const f = svgToCanvasInstructionMap[type]; if (!f) { - console.error(`Could not find drawing instructions for "${type}"`); + logService.error(`Could not find drawing instructions for "${type}"`); continue; } const args: string[] = instruction.substring(1).split(','); @@ -598,7 +602,8 @@ function drawVectorShape( deviceCellWidth: number, deviceCellHeight: number, fontSize: number, - devicePixelRatio: number + devicePixelRatio: number, + logService: ILogService ): void { // Clip the cell to make sure drawing doesn't occur beyond bounds const clipRegion = new Path2D(); @@ -619,7 +624,7 @@ function drawVectorShape( } const f = svgToCanvasInstructionMap[type]; if (!f) { - console.error(`Could not find drawing instructions for "${type}"`); + logService.error(`Could not find drawing instructions for "${type}"`); continue; } const args: string[] = instruction.substring(1).split(',');