From 32ffb7012c0231b9ff2e0d60213005252352b0fc Mon Sep 17 00:00:00 2001 From: zhuxudong Date: Mon, 21 Jul 2025 18:13:17 +0800 Subject: [PATCH 1/3] fix: get gl lost state immediately --- packages/core/src/Engine.ts | 5 +---- packages/rhi-webgl/src/WebGLGraphicDevice.ts | 4 ++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/core/src/Engine.ts b/packages/core/src/Engine.ts index 8a7859be1..a62e93844 100644 --- a/packages/core/src/Engine.ts +++ b/packages/core/src/Engine.ts @@ -131,7 +131,6 @@ export class Engine extends EventDispatcher { private _destroyed: boolean = false; private _frameInProcess: boolean = false; private _waitingDestroy: boolean = false; - private _isDeviceLost: boolean = false; private _waitingGC: boolean = false; private _postProcessPasses = new Array(); private _activePostProcessPasses = new Array(); @@ -381,7 +380,7 @@ export class Engine extends EventDispatcher { } // Render scene and fire `onBeginRender` and `onEndRender` - if (!this._isDeviceLost) { + if (!this._hardwareRenderer.isContextLost) { this._render(scenes); } @@ -652,7 +651,6 @@ export class Engine extends EventDispatcher { } private _onDeviceLost(): void { - this._isDeviceLost = true; // Lose graphic resources this.resourceManager._lostGraphicResources(); console.log("Device lost."); @@ -677,7 +675,6 @@ export class Engine extends EventDispatcher { .then(() => { console.log("Graphic resource content restored.\n\n" + "Device restored."); this.dispatch("devicerestored", this); - this._isDeviceLost = false; }) .catch((error) => { console.error(error); diff --git a/packages/rhi-webgl/src/WebGLGraphicDevice.ts b/packages/rhi-webgl/src/WebGLGraphicDevice.ts index 3c8206a93..615199a09 100644 --- a/packages/rhi-webgl/src/WebGLGraphicDevice.ts +++ b/packages/rhi-webgl/src/WebGLGraphicDevice.ts @@ -135,6 +135,10 @@ export class WebGLGraphicDevice implements IHardwareRenderer { return this._gl; } + get isContextLost() { + return this.gl.isContextLost(); + } + get renderStates(): GLRenderStates { return this._renderStates; } From 1e8814a3bf840c8a42b23d6244641da1b7e965a8 Mon Sep 17 00:00:00 2001 From: zhuxudong Date: Mon, 21 Jul 2025 19:26:00 +0800 Subject: [PATCH 2/3] chore: rename --- packages/core/src/Engine.ts | 2 +- packages/rhi-webgl/src/WebGLGraphicDevice.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/core/src/Engine.ts b/packages/core/src/Engine.ts index a62e93844..6645114c1 100644 --- a/packages/core/src/Engine.ts +++ b/packages/core/src/Engine.ts @@ -380,7 +380,7 @@ export class Engine extends EventDispatcher { } // Render scene and fire `onBeginRender` and `onEndRender` - if (!this._hardwareRenderer.isContextLost) { + if (!this._hardwareRenderer.isContextLost()) { this._render(scenes); } diff --git a/packages/rhi-webgl/src/WebGLGraphicDevice.ts b/packages/rhi-webgl/src/WebGLGraphicDevice.ts index 615199a09..c92931e60 100644 --- a/packages/rhi-webgl/src/WebGLGraphicDevice.ts +++ b/packages/rhi-webgl/src/WebGLGraphicDevice.ts @@ -135,10 +135,6 @@ export class WebGLGraphicDevice implements IHardwareRenderer { return this._gl; } - get isContextLost() { - return this.gl.isContextLost(); - } - get renderStates(): GLRenderStates { return this._renderStates; } @@ -546,6 +542,10 @@ export class WebGLGraphicDevice implements IHardwareRenderer { extension.restoreContext(); } + isContextLost() { + return this.gl.isContextLost(); + } + resetState(): void { this._readFrameBuffer = null; this._enableGlobalDepthBias = false; From ed3d897a39ba991c24a64cb2c6c1b5ea9c5e466c Mon Sep 17 00:00:00 2001 From: zhuxudong Date: Mon, 21 Jul 2025 20:40:53 +0800 Subject: [PATCH 3/3] chore: opt code --- packages/core/src/shader/ShaderProgram.ts | 8 ++++---- packages/rhi-webgl/src/WebGLGraphicDevice.ts | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/core/src/shader/ShaderProgram.ts b/packages/core/src/shader/ShaderProgram.ts index 4f6054611..7f064511e 100644 --- a/packages/core/src/shader/ShaderProgram.ts +++ b/packages/core/src/shader/ShaderProgram.ts @@ -254,7 +254,6 @@ export class ShaderProgram { // Create program and link shader const program = gl.createProgram(); if (!program) { - console.warn("Context lost while create program."); return null; } @@ -285,7 +284,6 @@ export class ShaderProgram { const shader = gl.createShader(shaderType); if (!shader) { - console.warn("Context lost while create shader."); return null; } @@ -469,7 +467,8 @@ export class ShaderProgram { private _getUniformInfos(): WebGLActiveInfo[] { const gl = this._gl; const program = this._glProgram; - const uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); + // uniformCount is `null` when context lost. + const uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS) ?? 0; const uniformInfos = new Array(uniformCount); for (let i = 0; i < uniformCount; ++i) { @@ -485,7 +484,8 @@ export class ShaderProgram { const program = this._glProgram; const attributeInfos = new Array(); - const attributeCount = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES); + // attributeCount is `null` when context lost. + const attributeCount = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES) ?? 0; for (let i = 0; i < attributeCount; ++i) { const info = gl.getActiveAttrib(program, i); attributeInfos[i] = info; diff --git a/packages/rhi-webgl/src/WebGLGraphicDevice.ts b/packages/rhi-webgl/src/WebGLGraphicDevice.ts index c92931e60..98e39e7e5 100644 --- a/packages/rhi-webgl/src/WebGLGraphicDevice.ts +++ b/packages/rhi-webgl/src/WebGLGraphicDevice.ts @@ -542,6 +542,10 @@ export class WebGLGraphicDevice implements IHardwareRenderer { extension.restoreContext(); } + /** + * @remarks + * WebGL context loss and restore can happen at any GPU execution point. refs to: https://www.khronos.org/webgl/wiki/HandlingContextLost + */ isContextLost() { return this.gl.isContextLost(); }