v0.54.0: Kaleidostrobe at 60 fps, its big window on the GPU, two-tone gray mode, sync can go sooner

The plugin still steps at its own 25 fps, frame for frame; between frames
the turn continues, textures crossfade, and the cone follows a preview of
the newest audio, so beats land a refresh sooner. The big window replays
the original's GL calls through OpenGL (QPainter took ~40 ms a frame at
1080p); without GL it falls back. Gray mode is only the gray-mode colour on
the panel background. The sync slider goes to -50 ms (sooner).
This commit is contained in:
2026-10-14 12:26:38 -07:00
parent e38c751e39
commit 7ae55e757a
11 changed files with 514 additions and 121 deletions
+3 -9
View File
@@ -14,6 +14,7 @@ wave-table entry. The port has to reproduce them exactly.
import hashlib
import math
from pathlib import Path
from types import SimpleNamespace
import numpy as np
import pytest
@@ -238,7 +239,8 @@ class TestRenderer:
for _ in range(frames):
r.advance(_frame(dt=0.04))
ours = _paint(r, 96, 60)
gl = _gl_reference(r._frame, 96, 60)
layers, textures = r._shown # the in-between picture, not the frame
gl = _gl_reference(SimpleNamespace(layers=layers, textures=textures), 96, 60)
assert np.abs(ours - gl).max() <= 3
def test_fills_any_shape(self, qapp):
@@ -250,14 +252,6 @@ class TestRenderer:
magenta = (img[..., 0] == 255) & (img[..., 1] == 0) & (img[..., 2] == 255)
assert not magenta.any() # the cone reaches every corner
def test_dim_mode_is_gray(self, qapp):
r = KaleidostrobeRenderer()
for _ in range(5):
r.advance(_frame(dt=0.04))
r.dimmed = True # the widget then passes its gray
img = _paint(r, 120, 80, color="gray")
assert np.abs(img[..., 0] - img[..., 2]).max() <= 2 # gray tint
def test_pause_blanks_but_keeps_the_plugin(self, qapp):
r = KaleidostrobeRenderer()
for _ in range(5):