WGC capture fixes + high-resolution timer pacing for all loops

- Fix WGC capture_frame() returning stale frames (80k "frames" in 2s)
  by tracking new-frame events; return None when no new frame arrived
- Add draw_border config passthrough with Win11 22H2+ platform check
- Add high_resolution_timer() utility (timeBeginPeriod/EndPeriod)
- Switch all processing loops from time.time() to time.perf_counter()
- Wrap all loops with high_resolution_timer() for ~1ms sleep precision
- Add animation speed badges to static/gradient color strip cards

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-21 01:23:56 +03:00
parent 5004992f26
commit 84f063eee9
8 changed files with 514 additions and 444 deletions

View File

@@ -2,5 +2,6 @@
from .logger import setup_logging, get_logger
from .monitor_names import get_monitor_names, get_monitor_name, get_monitor_refresh_rates
from .timer import high_resolution_timer
__all__ = ["setup_logging", "get_logger", "get_monitor_names", "get_monitor_name", "get_monitor_refresh_rates"]
__all__ = ["setup_logging", "get_logger", "get_monitor_names", "get_monitor_name", "get_monitor_refresh_rates", "high_resolution_timer"]

View File

@@ -0,0 +1,34 @@
"""High-resolution timer utilities for precise sleep on Windows.
Windows default timer resolution is ~15.6ms, making time.sleep() very
imprecise for real-time loops (e.g. 60fps needs 16.67ms per frame).
Calling timeBeginPeriod(1) increases system timer resolution to 1ms,
making time.sleep() accurate to ~1ms. The calls are reference-counted
by Windows — each timeBeginPeriod must be paired with timeEndPeriod.
"""
import sys
from contextlib import contextmanager
@contextmanager
def high_resolution_timer():
"""Context manager that enables 1ms timer resolution on Windows.
Usage::
with high_resolution_timer():
while running:
...
time.sleep(remaining) # now accurate to ~1ms
"""
if sys.platform == "win32":
import ctypes
ctypes.windll.winmm.timeBeginPeriod(1)
try:
yield
finally:
if sys.platform == "win32":
import ctypes
ctypes.windll.winmm.timeEndPeriod(1)