mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-11 13:52:19 +00:00
Share the surface sample budget between placements in one task
Two triggers firing together (tiles loaded and a camera move end) ran two passes in the same task, each within 16 samples but 17 or more together. Placements in one task now share the budget; a placement that finds it spent continues in the next task, and that continuation starts a fresh budget.
This commit is contained in:
1 parent
982d197111
commit
9e2c424030
2 files changed
+36
-2
No files matched your search
@@ -135,6 +135,9 @@ export function createSurfacePoints(
|
||||
let revision = 0;
|
||||
let timer = null;
|
||||
let destroyed = false;
|
||||
// Placements in one task (two triggers at once) share one sample budget.
|
||||
let taskSamples = 0;
|
||||
let taskCounted = false;
|
||||
|
||||
function onScreen(position, size) {
|
||||
if (screenMargin === Infinity) return true;
|
||||
@@ -160,6 +163,12 @@ export function createSurfacePoints(
|
||||
return plausible(height) ? height : Number.NaN;
|
||||
}
|
||||
|
||||
// A pass continued by its own timer starts a new task's budget.
|
||||
function continuePlacing() {
|
||||
taskSamples = 0;
|
||||
place();
|
||||
}
|
||||
|
||||
// Points off screen are passed over until the next move or tile load.
|
||||
function place({ all = false } = {}) {
|
||||
if (all) revision++;
|
||||
@@ -169,7 +178,14 @@ export function createSurfacePoints(
|
||||
const size = engine.host.size();
|
||||
const tiles = engine.maps?.photorealActive?.() === true;
|
||||
const started = performance.now();
|
||||
let samples = 0;
|
||||
if (!taskCounted) {
|
||||
taskCounted = true;
|
||||
queueMicrotask(() => {
|
||||
taskSamples = 0;
|
||||
taskCounted = false;
|
||||
});
|
||||
}
|
||||
let samples = taskSamples;
|
||||
let visited = 0;
|
||||
let moved = false;
|
||||
let cameraGround;
|
||||
@@ -179,7 +195,7 @@ export function createSurfacePoints(
|
||||
const yieldPass = () => {
|
||||
if (changed) set.commit();
|
||||
if (changed || moved) request();
|
||||
timer = setTimeout(place, 0);
|
||||
timer = setTimeout(continuePlacing, 0);
|
||||
};
|
||||
for (let index = 0; index < points.length; index++) {
|
||||
const point = points[index];
|
||||
@@ -207,6 +223,7 @@ export function createSurfacePoints(
|
||||
if (estimate && tiles && !plausible(ground)) {
|
||||
if (cameraGround === undefined) {
|
||||
samples++;
|
||||
taskSamples = samples;
|
||||
cameraGround = groundUnderCamera(exclude);
|
||||
}
|
||||
ground = cameraGround;
|
||||
@@ -230,6 +247,7 @@ export function createSurfacePoints(
|
||||
return;
|
||||
}
|
||||
samples++;
|
||||
taskSamples = samples;
|
||||
const height = readSurface(engine, point.cartographic, {
|
||||
exclude,
|
||||
prefer: typeof prefer === 'function' ? prefer(point) : prefer,
|
||||
|
||||
@@ -293,3 +293,19 @@ test('no tile sample starts once the pass has used its time', async (t) => {
|
||||
`samples started at ${starts.join(', ')} ms`,
|
||||
);
|
||||
});
|
||||
|
||||
test('two placements in one task share one pass budget', async (t) => {
|
||||
const { engine, surface } = setup(t, 40);
|
||||
await engine.maps.setPhotorealTiles({});
|
||||
engine.fake.script('terrainHeight', 10);
|
||||
engine.fake.script('sampleHeight', 50);
|
||||
const sampled = t.mock.method(engine.surface, 'sampleHeight');
|
||||
surface.place();
|
||||
surface.place({ all: true });
|
||||
assert.ok(
|
||||
sampled.mock.callCount() <= 16,
|
||||
`${sampled.mock.callCount()} samples in one task`,
|
||||
);
|
||||
await new Promise((resolve) => setTimeout(resolve, 20));
|
||||
assert.ok(sampled.mock.callCount() > 16, 'the deferred placement ran');
|
||||
});
|
||||
Reference in new issue
Block a user