wren/val Public Public: anyone can read this; nobody can change it.

forked from benjivers/val

workbenchthis machine
Files d8171ac61b98b4396aabe0046391dd3bf2c33dd9
1
/**
2
 * The frame budget: what the last second of frames cost, and one knob.
3
 *
4
 * The renderer's price is the number of columns it draws, and the right
5
 * number is not knowable from here — it depends on the machine, the window,
6
 * the battery and whatever else the browser is doing. So it is measured: a
7
 * second of frames at a time, and if the mean frame is over the budget the
8
 * world is drawn a rung coarser (see resolution.js), and a rung finer again
9
 * when there is room.
10
 *
11
 * It must not flap, because a resolution changing twice a second is more
12
 * visible than a resolution that is simply low. Three things stop it:
13
 * coarsening and refining have different thresholds, refining needs two
14
 * windows of headroom in a row, and it never refines past the rung the
15
 * window started on.
16
 *
17
 * Measurement only. Nothing here is sent anywhere or told to the simulation.
18
 */
19
20
/** Seconds of frames behind one decision. */
21
export const WINDOW = 1;
22
/** Mean milliseconds a frame: over this is over budget, under this has room. */
23
export const SLOW = 20;
24
export const FAST = 13;
25
/** Windows of headroom before a rung is given back. */
26
export const PATIENCE = 2;
27
28
export function makeBudget(base = 0, max = 6) {
29
  return { base, max, level: base, frames: 0, total: 0, since: 0, good: 0, fps: 0, mean: 0 };
30
}
31
32
/**
33
 * One frame, `ms` long, drawn at `now` seconds. Returns true when the level
34
 * moved — the caller resizes what it draws into — and updates `fps` and
35
 * `mean` at the end of every window, for the readout to print.
36
 */
37
export function measure(budget, ms, now) {
38
  budget.frames++;
39
  budget.total += ms;
40
  if (budget.since === 0) {
41
    budget.since = now;
42
    return false;
43
  }
44
  const span = now - budget.since;
45
  if (span < WINDOW) return false;
46
  budget.mean = budget.total / budget.frames;
47
  budget.fps = budget.frames / span;
48
  budget.frames = 0;
49
  budget.total = 0;
50
  budget.since = now;
51
  if (budget.mean > SLOW) {
52
    budget.good = 0;
53
    if (budget.level >= budget.max) return false;
54
    budget.level++;
55
    return true;
56
  }
57
  if (budget.mean < FAST && budget.level > budget.base) {
58
    budget.good++;
59
    if (budget.good < PATIENCE) return false;
60
    budget.good = 0;
61
    budget.level--;
62
    return true;
63
  }
64
  budget.good = 0;
65
  return false;
66
}
↑↓ navigate ↵ open esc close
↑↓ navigate ↵ open esc close

Keyboard shortcuts