mirror of
https://github.com/GTNewHorizons/Angelica.git
synced 2026-10-25 20:22:22 +00:00
Settle frame pacing after an inconsistent vsync gate (#2197)
This commit is contained in:
1 parent
75a0278138
commit
338d94197c
2 files changed
+61
-1
No files matched your search
@@ -63,6 +63,7 @@ final class PacerCore {
|
||||
private boolean locked;
|
||||
private boolean probing;
|
||||
private boolean probeExhausted;
|
||||
private boolean gateAbandoned;
|
||||
private long probeLeadNanos;
|
||||
private boolean haveCandidate;
|
||||
private long candidateEndNanos;
|
||||
@@ -336,7 +337,7 @@ final class PacerCore {
|
||||
if (locked && framesSinceCandidate >= LOCK_FRAMES) dropLock();
|
||||
return;
|
||||
}
|
||||
if (haveCandidate && framesSinceCandidate <= LOCK_WINDOW) {
|
||||
if (!gateAbandoned && haveCandidate && framesSinceCandidate <= LOCK_WINDOW) {
|
||||
final long delta = sampleEnd - candidateEndNanos;
|
||||
final long k = (delta + refreshPeriodNanos / 2) / refreshPeriodNanos;
|
||||
if (k >= 1L && Math.abs(delta - k * refreshPeriodNanos) <= refreshPeriodNanos / LOCK_TOL_DIVISOR) {
|
||||
@@ -347,6 +348,7 @@ final class PacerCore {
|
||||
if (++inconsistentPairs >= LOCK_WINDOW) {
|
||||
dropLock();
|
||||
probeExhausted = true;
|
||||
gateAbandoned = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -358,6 +360,7 @@ final class PacerCore {
|
||||
private void armProbe() {
|
||||
probeLeadNanos = 0L;
|
||||
probeExhausted = false;
|
||||
gateAbandoned = false;
|
||||
}
|
||||
|
||||
private void dropLock() {
|
||||
|
||||
@@ -172,6 +172,51 @@ class PacerCoreTest {
|
||||
assertFalse(rig.core.probing(), "a gate proven off the grid must not be probed again");
|
||||
}
|
||||
|
||||
@Test
|
||||
void anAbandonedGateStaysRetiredThroughAnotherOnGridRun() {
|
||||
final Rig rig = new Rig(P60, true, 120);
|
||||
rig.feedRun(PacerCore.LOCK_PAIRS + 1, 20 * MS, 5 * MS, P60);
|
||||
assertTrue(rig.core.locked());
|
||||
assertEquals(60, rig.core.effectiveCapHz());
|
||||
|
||||
long end = 20 * MS + (PacerCore.LOCK_PAIRS + 1) * P60;
|
||||
for (int i = 0; i < PacerCore.LOCK_WINDOW + 1; i++) {
|
||||
end += P60 / 2;
|
||||
rig.feed(end, 5 * MS, end);
|
||||
}
|
||||
assertFalse(rig.core.locked());
|
||||
assertFalse(rig.core.probing());
|
||||
|
||||
for (int i = 0; i < PacerCore.LOCK_PAIRS + 1; i++) {
|
||||
end += P60;
|
||||
rig.feed(end, 5 * MS, end);
|
||||
}
|
||||
assertFalse(rig.core.locked(), "a retired inconsistent gate must not lock again");
|
||||
assertFalse(rig.core.probing());
|
||||
}
|
||||
|
||||
@Test
|
||||
void invalidateClearsAnAbandonedGate() {
|
||||
final Rig rig = new Rig(P60, true, 120);
|
||||
rig.feedRun(PacerCore.LOCK_PAIRS + 1, 20 * MS, 5 * MS, P60);
|
||||
|
||||
long end = 20 * MS + (PacerCore.LOCK_PAIRS + 1) * P60;
|
||||
for (int i = 0; i < PacerCore.LOCK_WINDOW + 1; i++) {
|
||||
end += P60 / 2;
|
||||
rig.feed(end, 5 * MS, end);
|
||||
}
|
||||
assertFalse(rig.core.locked());
|
||||
assertFalse(rig.core.probing());
|
||||
|
||||
rig.core.invalidate();
|
||||
for (int i = 0; i < PacerCore.LOCK_PAIRS + 1; i++) {
|
||||
end += P60;
|
||||
rig.feed(end, 5 * MS, end);
|
||||
}
|
||||
assertTrue(rig.core.locked());
|
||||
assertFalse(rig.core.probing());
|
||||
}
|
||||
|
||||
@Test
|
||||
void samplesFurtherApartThanTheLockWindowNeverPairUp() {
|
||||
final Rig rig = new Rig(P60, true, 0);
|
||||
@@ -372,6 +417,18 @@ class PacerCoreTest {
|
||||
assertEquals(P60, rig.presents.get(300) - rig.presents.get(299), "an expired probe must fall back to the exact cadence");
|
||||
}
|
||||
|
||||
@Test
|
||||
void anExpiredProbeLeadStillLocksWhenTheGateArrives() {
|
||||
final Rig rig = new Rig(P60, true, 0);
|
||||
for (int i = 0; i < 20; i++) rig.frame(4 * MS);
|
||||
assertFalse(rig.core.locked());
|
||||
assertFalse(rig.core.probing());
|
||||
|
||||
rig.feedRun(PacerCore.LOCK_PAIRS + 1, 20 * MS, 5 * MS, P60);
|
||||
assertTrue(rig.core.locked());
|
||||
assertFalse(rig.core.probing());
|
||||
}
|
||||
|
||||
@Test
|
||||
void mailboxIsNeverProbedAndNeverLocks() {
|
||||
final Rig rig = new Rig(P60, true, false, 0);
|
||||
|
||||
Reference in new issue
Block a user