Detect HW acceleration; default lava off on software renderer; release probe WebGL context

Probes UNMASKED_RENDERER_WEBGL once per page via a throwaway WebGL context; defaults the lava subsystem off on a positive software-renderer match or total WebGL failure; releases the throwaway context via WEBGL_lose_context after reading the renderer string to avoid exhausting the browser's per-page context limit.
This commit is contained in:
daniel-c-harvey
2026-06-26 10:41:07 -04:00
parent 0e8b85bbcb
commit 020a945843
6 changed files with 398 additions and 0 deletions
@@ -88,4 +88,93 @@ public class WaveformVisualizerControlStateTests
Assert.That(observedTheaterMode, Is.False);
}
// ── ApplyCapabilityDefault: the one-time HW-accel default-set ──
// No HW accel → lava defaults off, waveform stays on (the whole point of the feature).
[Test]
public void ApplyCapabilityDefault_NoHardwareAccel_LavaOffWaveformOn()
{
_state.ApplyCapabilityDefault(hardwareAccelerated: false);
Assert.Multiple(() =>
{
Assert.That(_state.LavaEnabled, Is.False);
Assert.That(_state.WaveformEnabled, Is.True);
});
}
// HW accel present → no change; lava keeps its shipped on-default (the common case is untouched).
[Test]
public void ApplyCapabilityDefault_HardwareAccelerated_LavaStaysOn()
{
_state.ApplyCapabilityDefault(hardwareAccelerated: true);
Assert.Multiple(() =>
{
Assert.That(_state.LavaEnabled, Is.True);
Assert.That(_state.WaveformEnabled, Is.True);
});
}
// No HW accel raises Changed once so the controls UI / bridge / theater observers all react.
[Test]
public void ApplyCapabilityDefault_NoHardwareAccel_RaisesChanged()
{
var raised = 0;
_state.Changed += () => raised++;
_state.ApplyCapabilityDefault(hardwareAccelerated: false);
Assert.That(raised, Is.EqualTo(1));
}
// HW accel present must not churn observers — no Changed when nothing changed.
[Test]
public void ApplyCapabilityDefault_HardwareAccelerated_DoesNotRaiseChanged()
{
var raised = 0;
_state.Changed += () => raised++;
_state.ApplyCapabilityDefault(hardwareAccelerated: true);
Assert.That(raised, Is.Zero);
}
// Guarded to once per session: a second call cannot re-clobber, even with a different verdict.
[Test]
public void ApplyCapabilityDefault_SecondCall_IsNoOp()
{
_state.ApplyCapabilityDefault(hardwareAccelerated: true); // first call wins (accelerated → on)
_state.ApplyCapabilityDefault(hardwareAccelerated: false); // must be ignored
Assert.That(_state.LavaEnabled, Is.True);
}
// Must not override an explicit in-session toggle: once applied, a user re-enabling lava on a
// software renderer sticks — a later (guarded) call never reverts it.
[Test]
public void ApplyCapabilityDefault_DoesNotOverrideExplicitUserToggle()
{
_state.ApplyCapabilityDefault(hardwareAccelerated: false); // default: lava off
_state.LavaEnabled = true; // user re-enables at their own risk
_state.ApplyCapabilityDefault(hardwareAccelerated: false); // guarded → no-op
Assert.That(_state.LavaEnabled, Is.True);
}
// No HW accel while Theater Mode is on with only lava active → coercion exits theater in the same
// cycle (lava off + waveform off would strand theater; here waveform stays on, but verify the
// coercion path is exercised when it WOULD strand).
[Test]
public void ApplyCapabilityDefault_NoHardwareAccel_CoercesStrandedTheater()
{
_state.WaveformEnabled = false; // only lava active
_state.TheaterMode = true;
_state.ApplyCapabilityDefault(hardwareAccelerated: false); // lava off → both off → strand
Assert.That(_state.TheaterMode, Is.False);
}
}