mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-10 13:04:36 +00:00
Restore on webgl context loss (#3968)
## Description: When WebGL context is lost, restore context and all elements. In GameView, handle potentially transient undefined states during context loss gracefully. Test with chrome://gpucrash from another tab, then return to the game tab to see it being restored (This fake gpucrash only works once sometimes. Because the second time the browser might reject the tab it thinks caused the gpu crash, access to hardware acceleration. And after even more tries even disables it browser-wide. A browser restart resets it in that case.) ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced ## Please put your Discord username so you can be contacted if a bug or regression is found: tryout33
This commit is contained in:
@@ -68,7 +68,7 @@ import { createCanvas } from "./Utils";
|
||||
import { WebGLFrameBuilder } from "./WebGLFrameBuilder";
|
||||
import { createRenderer, GameRenderer } from "./hud/GameRenderer";
|
||||
import { GameView as WebGLGameView } from "./render/gl";
|
||||
import { ALL_UNIT_TYPES } from "./render/types";
|
||||
import { ALL_UNIT_TYPES, UnitState } from "./render/types";
|
||||
import { SoundManager } from "./sound/SoundManager";
|
||||
|
||||
export interface LobbyConfig {
|
||||
@@ -372,7 +372,34 @@ function mountWebGLFrameLoop(
|
||||
};
|
||||
requestAnimationFrame(driveFrame);
|
||||
|
||||
return { builder: new WebGLFrameBuilder(view) };
|
||||
const builder = new WebGLFrameBuilder(view);
|
||||
|
||||
// When context is lost and restored, WebGL loses all textures and geometry.
|
||||
// Force a full re-upload of the simulation state.
|
||||
view.on("contextrestored", () => {
|
||||
builder.clearCaches();
|
||||
|
||||
// Full upload of terrain, territory & trail state
|
||||
const mapSize = mapWidth * mapHeight;
|
||||
const allRefs = new Array(mapSize);
|
||||
const allTerrain = new Uint8Array(mapSize);
|
||||
for (let i = 0; i < mapSize; i++) {
|
||||
allRefs[i] = i;
|
||||
allTerrain[i] = gameView.terrainByte(i);
|
||||
}
|
||||
view.applyTerrainDelta(allRefs, allTerrain);
|
||||
|
||||
const frameData = gameView.frameData();
|
||||
view.uploadTileAndTrailState(frameData.tileState, frameData.trailState);
|
||||
|
||||
// Structures and railroads normally skip GPU upload unless marked dirty, now force
|
||||
view.updateStructures(frameData.units as Map<number, UnitState>);
|
||||
view.uploadRailroadState(frameData.railroadState);
|
||||
|
||||
builder.update(gameView);
|
||||
});
|
||||
|
||||
return { builder };
|
||||
}
|
||||
|
||||
async function createClientGame(
|
||||
|
||||
Reference in New Issue
Block a user