mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 11:24:00 +00:00
Read a parked globe's WebGL context from the one it was built with instead of asking its canvas during a switch
Asking the canvas again during the switch made the reuse depend on getContext at that moment: with new contexts refused (qa-strict-failure-matrix, cold Navara to Cesium) the rollback to the parked Navara threw and left no globe.
This commit is contained in:
1 parent
90d64e6916
commit
726e201314
2 files changed
+25
-8
No files matched your search
@@ -9,11 +9,8 @@ export function createRendererCache() {
|
||||
let entry = idle.get(kind);
|
||||
idle.delete(kind);
|
||||
// loseContext() takes effect before its queued DOM event is delivered.
|
||||
// Check the existing context too, before resuming a parked render loop.
|
||||
const canvas = entry?.scene.engine.host.canvas;
|
||||
const context =
|
||||
canvas?.getContext?.('webgl2') ?? canvas?.getContext?.('webgl');
|
||||
if (entry && (entry.lost || context?.isContextLost())) {
|
||||
// Check the context itself too, before resuming a parked render loop.
|
||||
if (entry && (entry.lost || entry.context?.isContextLost?.())) {
|
||||
entry.dispose();
|
||||
entry = null;
|
||||
}
|
||||
@@ -39,7 +36,13 @@ export function createRendererCache() {
|
||||
container,
|
||||
defer: (fn) => cleanups.push(fn),
|
||||
});
|
||||
entry = { container, scene, dispose, lost: false };
|
||||
// The context the globe draws with, read once while it is new: a
|
||||
// switch reads its state and never asks the canvas again (a canvas
|
||||
// asked for another context type would create one).
|
||||
const canvas = scene.engine.host.canvas;
|
||||
const context =
|
||||
canvas.getContext?.('webgl2') ?? canvas.getContext?.('webgl') ?? null;
|
||||
entry = { container, scene, dispose, lost: false, context };
|
||||
scene.engine.host.canvas.addEventListener(
|
||||
'webglcontextlost',
|
||||
() => {
|
||||
|
||||
@@ -27,7 +27,11 @@ test('a parked renderer is reused, but a lost context is disposed before rebuild
|
||||
defer(() => {
|
||||
released += 1;
|
||||
});
|
||||
const canvas = new EventTarget();
|
||||
const context = { lost: false, isContextLost: () => context.lost };
|
||||
canvas.getContext = (type) => (type === 'webgl2' ? context : null);
|
||||
return {
|
||||
context,
|
||||
suspend() {
|
||||
this.running = false;
|
||||
},
|
||||
@@ -35,7 +39,7 @@ test('a parked renderer is reused, but a lost context is disposed before rebuild
|
||||
this.running = true;
|
||||
},
|
||||
engine: {
|
||||
host: { container, canvas: new EventTarget() },
|
||||
host: { container, canvas },
|
||||
render: { request() {} },
|
||||
},
|
||||
};
|
||||
@@ -49,13 +53,23 @@ test('a parked renderer is reused, but a lost context is disposed before rebuild
|
||||
release();
|
||||
assert.equal(first.running, false);
|
||||
assert.equal(first.engine.host.container.isConnected, false);
|
||||
// A parked renderer whose canvas no longer hands out contexts is still
|
||||
// reused when its own context is alive.
|
||||
first.engine.host.canvas.getContext = () => {
|
||||
throw new Error('getContext called during a switch');
|
||||
};
|
||||
assert.equal(await open(), first);
|
||||
assert.equal(first.running, true);
|
||||
assert.equal(first.engine.host.container.isConnected, true);
|
||||
cache.retain('navara');
|
||||
release();
|
||||
// The WebGL context is already lost, but its DOM event has not fired.
|
||||
first.engine.host.canvas.getContext = () => ({ isContextLost: () => true });
|
||||
// The switch reads the context the globe was built with and never asks
|
||||
// the canvas again (a QA or driver failure of getContext must not decide).
|
||||
first.context.lost = true;
|
||||
first.engine.host.canvas.getContext = () => {
|
||||
throw new Error('getContext called during a switch');
|
||||
};
|
||||
const second = await open();
|
||||
assert.notEqual(second, first);
|
||||
assert.equal(released, 1);
|
||||
|
||||
Reference in new issue
Block a user