fix fps toggle

This commit is contained in:
KingKDot
2026-06-07 00:05:35 -05:00
parent e9a61ecd9b
commit c3f34753c6
4 changed files with 66 additions and 2 deletions
@@ -432,3 +432,29 @@ func TestCaptureAndSend_CancelledContext(t *testing.T) {
// SHOULD handle gracefully, may or may not send depending on timing :sob: // SHOULD handle gracefully, may or may not send depending on timing :sob:
_ = CaptureAndSend(ctx, env) _ = CaptureAndSend(ctx, env)
} }
func TestSetFrameFlowTargetFPSScalesHighFPS(t *testing.T) {
t.Setenv("OVERLORD_DESKTOP_IN_FLIGHT_FRAMES", "")
ResetFrameSlots()
SetFrameFlowTargetFPS(60)
if got := activeFrameSlotLimit(); got != 2 {
t.Fatalf("expected 60 fps slot limit 2, got %d", got)
}
SetFrameFlowTargetFPS(120)
if got := activeFrameSlotLimit(); got != 4 {
t.Fatalf("expected 120 fps slot limit 4, got %d", got)
}
SetFrameFlowTargetFPS(240)
if got := activeFrameSlotLimit(); got != 8 {
t.Fatalf("expected 240 fps slot limit 8, got %d", got)
}
}
func TestSetFrameFlowTargetFPSEnvOverride(t *testing.T) {
t.Setenv("OVERLORD_DESKTOP_IN_FLIGHT_FRAMES", "12")
ResetFrameSlots()
SetFrameFlowTargetFPS(240)
if got := activeFrameSlotLimit(); got != 12 {
t.Fatalf("expected env slot limit 12, got %d", got)
}
}
@@ -1,16 +1,20 @@
package capture package capture
import ( import (
"os"
"strconv"
"strings"
"sync/atomic" "sync/atomic"
"time" "time"
) )
const maxInFlightFrames int64 = 2 const defaultMaxInFlightFrames int64 = 2
var ( var (
inFlightFrames atomic.Int64 inFlightFrames atomic.Int64
frameAckSeen atomic.Bool frameAckSeen atomic.Bool
lastAckNano atomic.Int64 lastAckNano atomic.Int64
maxFrameSlots atomic.Int64
) )
func AcquireFrameSlot() bool { func AcquireFrameSlot() bool {
@@ -20,7 +24,7 @@ func AcquireFrameSlot() bool {
for { for {
cur := inFlightFrames.Load() cur := inFlightFrames.Load()
if cur >= maxInFlightFrames { if cur >= activeFrameSlotLimit() {
lastAck := lastAckNano.Load() lastAck := lastAckNano.Load()
if lastAck > 0 && time.Since(time.Unix(0, lastAck)) > time.Second { if lastAck > 0 && time.Since(time.Unix(0, lastAck)) > time.Second {
inFlightFrames.Store(0) inFlightFrames.Store(0)
@@ -47,3 +51,33 @@ func ResetFrameSlots() {
frameAckSeen.Store(false) frameAckSeen.Store(false)
lastAckNano.Store(0) lastAckNano.Store(0)
} }
func SetFrameFlowTargetFPS(fps int) {
limit := defaultMaxInFlightFrames
switch {
case fps >= 180:
limit = 8
case fps >= 120:
limit = 4
}
if env := strings.TrimSpace(os.Getenv("OVERLORD_DESKTOP_IN_FLIGHT_FRAMES")); env != "" {
if v, err := strconv.Atoi(env); err == nil {
switch {
case v < 1:
limit = 1
case v > 32:
limit = 32
default:
limit = int64(v)
}
}
}
maxFrameSlots.Store(limit)
}
func activeFrameSlotLimit() int64 {
if limit := maxFrameSlots.Load(); limit > 0 {
return limit
}
return defaultMaxInFlightFrames
}
@@ -33,6 +33,7 @@ func DesktopStart(ctx context.Context, env *rt.Env) error {
fps := activeDesktopTargetFPS() fps := activeDesktopTargetFPS()
interval := time.Second / time.Duration(fps) interval := time.Second / time.Duration(fps)
capture.SetH264TargetFPS(fps) capture.SetH264TargetFPS(fps)
capture.SetFrameFlowTargetFPS(fps)
log.Printf("desktop: starting stream (target fps %d)", fps) log.Printf("desktop: starting stream (target fps %d)", fps)
ticker := time.NewTicker(interval) ticker := time.NewTicker(interval)
defer ticker.Stop() defer ticker.Stop()
@@ -47,6 +48,7 @@ func DesktopStart(ctx context.Context, env *rt.Env) error {
if fps != currentFPS { if fps != currentFPS {
currentFPS = fps currentFPS = fps
capture.SetH264TargetFPS(fps) capture.SetH264TargetFPS(fps)
capture.SetFrameFlowTargetFPS(fps)
ticker.Reset(time.Second / time.Duration(fps)) ticker.Reset(time.Second / time.Duration(fps))
log.Printf("desktop: target fps changed to %d", fps) log.Printf("desktop: target fps changed to %d", fps)
} }
@@ -73,6 +75,7 @@ func SetDesktopTargetFPS(fps int) int {
fps = clampDesktopTargetFPS(fps) fps = clampDesktopTargetFPS(fps)
desktopTargetFPS.Store(int64(fps)) desktopTargetFPS.Store(int64(fps))
capture.SetH264TargetFPS(fps) capture.SetH264TargetFPS(fps)
capture.SetFrameFlowTargetFPS(fps)
return fps return fps
} }
@@ -788,6 +788,7 @@ import { createKeyboardCapture } from "./keyboard-capture.js";
pushInputToggles(); pushInputToggles();
pushCaptureToggles(); pushCaptureToggles();
if (qualitySlider) pushQuality(qualitySlider.value); if (qualitySlider) pushQuality(qualitySlider.value);
pushTargetFps();
pushResolution(); pushResolution();
} else { } else {
setStreamState("idle", "Stopped"); setStreamState("idle", "Stopped");