fix(infrastructure): stop idle republishing and respect settled terrain

Skip unchanged overlay cohorts while detecting moved positions and lifecycle changes. Defer ground sampling until visible terrain settles, retain the loaded surface as a floor, and preserve roof heights and bounded retries. Keep regression and idle-render gates intact.
This commit is contained in:
Sameh Khamis committed 2026-09-11 08:59:32 -07:00
1 parent 6dd00d1e76
commit b5568de9fa
6 files changed
+124 -7

No files matched your search

+4
View File
@@ -13,6 +13,10 @@ of current runtime behavior, see [`docs/CURRENT-STATE.md`](docs/CURRENT-STATE.md
## [Unreleased] ## [Unreleased]
- Unchanged local infrastructure overlays no longer sustain idle rendering.
Ground samples wait for visible terrain to settle and cannot place a marker
below its loaded surface; roofs and valid below-sea-level heights are retained.
- Datacenter and dam marker stems use bounded, zoom-dependent active sets with - Datacenter and dam marker stems use bounded, zoom-dependent active sets with
stable selection during camera motion. Close-up stems scale to the actual stable selection during camera motion. Close-up stems scale to the actual
camera distance; source totals and submarine cables remain unchanged. camera distance; source totals and submarine cables remain unchanged.
+5
View File
@@ -8,6 +8,11 @@ and 420 below 200 km. Selection favors existing label priority and nearby
features, retains stable choices across small camera movements, and refreshes features, retains stable choices across small camera movements, and refreshes
during continuous motion. Disable/re-enable resets selection cleanly. during continuous motion. Disable/re-enable resets selection cleanly.
Close-up stem sizing uses camera-to-feature distance without a 5 km minimum. Close-up stem sizing uses camera-to-feature distance without a 5 km minimum.
Unchanged overlay entries do not request another frame; moved positions,
changed membership and re-enabling still publish. Ground sampling waits for
visible globe tiles to settle and uses valid loaded terrain as a floor while
retaining rooftop and below-sea-level elevations. A hidden globe does not
constrain photoreal geometry, and retry work remains bounded.
The submarine-cable renderer is unchanged. These limits bound active stem work; The submarine-cable renderer is unchanged. These limits bound active stem work;
they do not reduce the materialized entity count or establish an FPS gain. they do not reduce the materialized entity count or establish an FPS gain.
+21 -6
View File
@@ -296,12 +296,27 @@ try {
// ── parked-idle honesty: the LOD walk must not force continuous render ─ // ── parked-idle honesty: the LOD walk must not force continuous render ─
await new Promise((r) => setTimeout(r, 4_000)); await new Promise((r) => setTimeout(r, 4_000));
const idle = await page.evaluate(() => new Promise((resolve) => { const idle = await page.evaluate(async () => {
const scene = window.__godsEyeView.viewer.scene; const { getRenderGovernorDiagnostics } = await import('/src/renderGovernor.js');
let renders = 0; return new Promise((resolve) => {
const remove = scene.postRender.addEventListener(() => { renders += 1; }); const scene = window.__godsEyeView.viewer.scene;
setTimeout(() => { remove(); resolve({ renders }); }, 5_000); const startedAt = Date.now();
})); const tilesLoadedBefore = scene.globe.tilesLoaded;
let renders = 0;
let framesWithPendingTiles = 0;
const remove = scene.postRender.addEventListener(() => {
renders += 1;
if (!scene.globe.tilesLoaded) framesWithPendingTiles += 1;
});
setTimeout(() => {
remove();
const governor = getRenderGovernorDiagnostics();
resolve({ renders, tilesLoadedBefore, tilesLoadedAfter: scene.globe.tilesLoaded,
framesWithPendingTiles, mode: governor.mode, holds: governor.holds,
requests: governor.recentRequests.filter(request => request.at >= startedAt) });
}, 5_000);
});
});
report(CONTROL report(CONTROL
? 'parked idle, control (postRender fires / 5s)' ? 'parked idle, control (postRender fires / 5s)'
: 'parked idle with infra ON (postRender fires / 5s)', idle); : 'parked idle with infra ON (postRender fires / 5s)', idle);
+28
View File
@@ -225,6 +225,11 @@ export function createLocalInfrastructureOverlayPublisher({
let visible = false; let visible = false;
let published = false; let published = false;
let destroyed = false; let destroyed = false;
// Local entries have immutable metadata and a mutable Cartesian position.
// Snapshot coordinates: retaining only the entry reference would miss a
// stem tip moving in place. Republishing an unchanged cohort invalidates
// the host and can sustain a render loop when frames exceed the 450 ms walk.
let lastPublication = null;
const sourceOptions = { const sourceOptions = {
cohortLimit: LOCAL_OVERLAY_COHORT_LIMIT, cohortLimit: LOCAL_OVERLAY_COHORT_LIMIT,
collisionCapacity: LOCAL_OVERLAY_COLLISION_CAPACITY, collisionCapacity: LOCAL_OVERLAY_COLLISION_CAPACITY,
@@ -239,7 +244,18 @@ export function createLocalInfrastructureOverlayPublisher({
}, },
publish(entries) { publish(entries) {
if (destroyed || !visible) return; if (destroyed || !visible) return;
if (lastPublication && entries.length === lastPublication.length
&& entries.every((entry, index) => {
const previous = lastPublication[index];
return entry === previous.entry
&& entry.position?.x === previous.x
&& entry.position?.y === previous.y
&& entry.position?.z === previous.z;
})) return;
host.setEntries(sourceId, entries, sourceOptions); host.setEntries(sourceId, entries, sourceOptions);
lastPublication = entries.map(entry => ({
entry, x: entry.position?.x, y: entry.position?.y, z: entry.position?.z,
}));
published = entries.length > 0; published = entries.length > 0;
}, },
hide() { hide() {
@@ -248,6 +264,7 @@ export function createLocalInfrastructureOverlayPublisher({
if (visible) host.setVisible(sourceId, false); if (visible) host.setVisible(sourceId, false);
visible = false; visible = false;
published = false; published = false;
lastPublication = null;
}, },
destroy() { destroy() {
if (destroyed) return; if (destroyed) return;
@@ -255,6 +272,7 @@ export function createLocalInfrastructureOverlayPublisher({
if (visible) host.setVisible(sourceId, false); if (visible) host.setVisible(sourceId, false);
visible = false; visible = false;
published = false; published = false;
lastPublication = null;
destroyed = true; destroyed = true;
}, },
}; };
@@ -897,6 +915,8 @@ function sampleLocalGroundHeight(viewer, record, now) {
if (record.groundSampled || !viewer.scene.sampleHeightSupported) return false; if (record.groundSampled || !viewer.scene.sampleHeightSupported) return false;
if (now - record.lastGroundSampleMs < GROUND_SAMPLE_RETRY_MS) return false; if (now - record.lastGroundSampleMs < GROUND_SAMPLE_RETRY_MS) return false;
record.lastGroundSampleMs = now; record.lastGroundSampleMs = now;
const globe = viewer.scene.globe;
if (globe?.show && globe.tilesLoaded === false) return false;
let sampled; let sampled;
try { try {
sampled = viewer.scene.sampleHeight(record.carto, [record.entity]); sampled = viewer.scene.sampleHeight(record.carto, [record.entity]);
@@ -904,6 +924,14 @@ function sampleLocalGroundHeight(viewer, record, now) {
return false; // tiles not ready; retry on a later bounded update return false; // tiles not ready; retry on a later bounded update
} }
if (!Number.isFinite(sampled) || Math.abs(sampled) > GROUND_SAMPLE_MAX_ABS_HEIGHT_M) return false; if (!Number.isFinite(sampled) || Math.abs(sampled) > GROUND_SAMPLE_MAX_ABS_HEIGHT_M) return false;
// A coarse scene-depth sample can lie below the terrain already loaded by
// the visible globe. Keep that terrain as a floor while allowing roofs and
// valid below-sea-level elevations. Photoreal scenes hide the globe, so its
// inactive terrain must not constrain their geometry.
const terrainHeight = globe?.show ? globe.getHeight?.(record.carto) : undefined;
if (Number.isFinite(terrainHeight) && Math.abs(terrainHeight) <= GROUND_SAMPLE_MAX_ABS_HEIGHT_M) {
sampled = Math.max(sampled, terrainHeight);
}
record.groundSampled = true; record.groundSampled = true;
record.groundHeight = sampled; record.groundHeight = sampled;
Cesium.Cartesian3.fromRadians( Cesium.Cartesian3.fromRadians(
+65
View File
@@ -314,6 +314,33 @@ test('local overlay publisher owns add/remove/visibility lifecycle and becomes i
assert.deepEqual(calls[7], ['visible', 'local-datacenters', false]); assert.deepEqual(calls[7], ['visible', 'local-datacenters', false]);
}); });
test('slow parked frames do not keep republishing the same local overlay cohort', async (t) => {
const env = await createRealLocalLayerHarness();
const clock = installFakeClock(t);
t.after(() => { env.layer.destroy(env.viewer); env.cleanup(); });
const publications = () => env.hostCalls.filter(([type]) => type === 'entries');
env.preRender.raise();
assert.equal(publications().length, 1);
assert.ok(publications()[0][2].length > 0, 'the initial cohort must be populated');
for (let i = 0; i < 6; i++) {
clock.advance(1_000); // Every slow frame passes the 450 ms source throttle.
env.preRender.raise();
}
assert.equal(publications().length, 1,
'unchanged publication invalidates the real host and requests another slow frame');
const camera = env.viewer.camera.positionWC;
env.viewer.camera.positionWC = Cesium.Cartesian3.add(camera,
new Cesium.Cartesian3(10_000, 0, 0), new Cesium.Cartesian3());
env.moveEnd.raise();
env.preRender.raise();
assert.equal(publications().length, 2, 'changed stem positions must still reach the host');
env.layer.disable(env.viewer);
await env.layer.enable(env.viewer);
env.preRender.raise();
assert.equal(publications().length, 3, 're-enable must republish after clearing the host');
});
test('real layer disable clears its published host entries and balances settle listeners', async () => { test('real layer disable clears its published host entries and balances settle listeners', async () => {
const env = await createRealLocalLayerHarness(); const env = await createRealLocalLayerHarness();
env.preRender.raise(); env.preRender.raise();
@@ -683,6 +710,44 @@ function governorReasons() {
return getRenderGovernorDiagnostics().recentRequests.map((entry) => entry.reason); return getRenderGovernorDiagnostics().recentRequests.map((entry) => entry.reason);
} }
test('ground sampling waits for visible globe tiles before caching a height', async (t) => {
const env = await createRealLocalLayerHarness({
sampleHeightSupported: true, sampleHeight: () => 117,
});
const clock = installFakeClock(t);
t.after(() => { env.layer.destroy(env.viewer); env.cleanup(); });
env.viewer.scene.globe = { show: true, tilesLoaded: false, getHeight: () => 117 };
setCameraAltitude(env, 20_000);
env.preRender.raise();
assert.equal(env.sampleCalls.count, 0, 'streaming terrain must not become a permanent coarse sample');
assert.ok(Math.abs(baseHeightM(env)) < 0.01);
env.viewer.scene.globe.tilesLoaded = true;
clock.advance(2_100);
env.preRender.raise();
assert.equal(env.sampleCalls.count, 1, 'the existing retry must sample the settled scene');
assert.ok(Math.abs(baseHeightM(env) - 117) < 0.01);
});
for (const [terrainHeight, sampledHeight, expectedHeight, globeShown] of [
[117, -2238, 117, true],
[-400, -410, -400, true],
[117, 180, 180, true],
[117, -20, -20, false],
]) {
test(`ground sampling respects terrain ${terrainHeight} and geometry ${sampledHeight} with globe ${globeShown}`, async (t) => {
const env = await createRealLocalLayerHarness({
sampleHeightSupported: true, sampleHeight: () => sampledHeight,
});
installFakeClock(t);
t.after(() => { env.layer.destroy(env.viewer); env.cleanup(); });
env.viewer.scene.globe = { show: globeShown, getHeight: () => terrainHeight };
setCameraAltitude(env, 20_000);
env.preRender.raise();
assert.ok(Math.abs(baseHeightM(env) - expectedHeight) < 0.01,
`base ${baseHeightM(env)} must respect the visible terrain without flattening roofs or below-sea-level terrain`);
});
}
test('a failed ground sample schedules the retry frame the idle governor would never produce', async (t) => { test('a failed ground sample schedules the retry frame the idle governor would never produce', async (t) => {
const env = await createRealLocalLayerHarness({ sampleHeightSupported: true }); const env = await createRealLocalLayerHarness({ sampleHeightSupported: true });
_resetRenderGovernorForTest(); _resetRenderGovernorForTest();
+1 -1
View File
@@ -58,7 +58,7 @@ test('infraLodBudget band boundaries are inclusive at the lower edge', () => {
assert.deepEqual(infraLodBudget(INFRA_LOD_REGIONAL_HEIGHT_M - 1), { activeLimit: INFRA_LOD_ACTIVE_MAX }); assert.deepEqual(infraLodBudget(INFRA_LOD_REGIONAL_HEIGHT_M - 1), { activeLimit: INFRA_LOD_ACTIVE_MAX });
}); });
test('infraLodBudget treats non-finite / negative height as the global (cheapest) band', () => { test('infraLodBudget uses the global band for non-finite height and clamps negative height to zero', () => {
assert.deepEqual(infraLodBudget(undefined), { activeLimit: INFRA_LOD_ACTIVE_MIN }); assert.deepEqual(infraLodBudget(undefined), { activeLimit: INFRA_LOD_ACTIVE_MIN });
assert.deepEqual(infraLodBudget(NaN), { activeLimit: INFRA_LOD_ACTIVE_MIN }); assert.deepEqual(infraLodBudget(NaN), { activeLimit: INFRA_LOD_ACTIVE_MIN });
assert.deepEqual(infraLodBudget(Number.POSITIVE_INFINITY), { activeLimit: INFRA_LOD_ACTIVE_MIN }); assert.deepEqual(infraLodBudget(Number.POSITIVE_INFINITY), { activeLimit: INFRA_LOD_ACTIVE_MIN });