Files

142 lines
2.8 KiB
Go
Raw Permalink Normal View History

2026-04-08 14:14:09 -05:00
package capture
import (
2026-06-07 00:05:35 -05:00
"os"
"strconv"
"strings"
"sync"
2026-04-08 14:14:09 -05:00
"sync/atomic"
"time"
)
2026-06-07 00:05:35 -05:00
const defaultMaxInFlightFrames int64 = 2
2026-04-08 14:14:09 -05:00
var (
inFlightFrames atomic.Int64
frameAckSeen atomic.Bool
lastAckNano atomic.Int64
2026-06-07 00:05:35 -05:00
maxFrameSlots atomic.Int64
frameStreamsMu sync.Mutex
frameStreams = make(map[string]int)
2026-04-08 14:14:09 -05:00
)
func AcquireFrameSlot() bool {
if !frameAckSeen.Load() {
return true
}
for {
cur := inFlightFrames.Load()
2026-06-07 00:05:35 -05:00
if cur >= activeFrameSlotLimit() {
2026-04-08 14:14:09 -05:00
lastAck := lastAckNano.Load()
if lastAck > 0 && time.Since(time.Unix(0, lastAck)) > time.Second {
inFlightFrames.Store(0)
continue
}
2026-07-06 20:19:38 -05:00
statFrameSlotSkips.Add(1)
2026-04-08 14:14:09 -05:00
return false
}
if inFlightFrames.CompareAndSwap(cur, cur+1) {
return true
}
}
}
func ReleaseFrameSlot() {
frameAckSeen.Store(true)
lastAckNano.Store(time.Now().UnixNano())
if inFlightFrames.Add(-1) < 0 {
inFlightFrames.Store(0)
}
}
func ResetFrameSlots() {
inFlightFrames.Store(0)
frameAckSeen.Store(false)
lastAckNano.Store(0)
}
2026-06-07 00:05:35 -05:00
func SetFrameFlowTargetFPS(fps int) {
maxFrameSlots.Store(frameSlotLimitForFPS(fps))
}
func StartFrameFlowStream(stream string, fps int) {
frameStreamsMu.Lock()
frameStreams[stream] = fps
applyActiveFrameStreamLimitLocked()
frameStreamsMu.Unlock()
}
func UpdateFrameFlowStream(stream string, fps int) {
frameStreamsMu.Lock()
if _, active := frameStreams[stream]; active {
frameStreams[stream] = fps
applyActiveFrameStreamLimitLocked()
}
frameStreamsMu.Unlock()
}
func StopFrameFlowStream(stream string) {
frameStreamsMu.Lock()
delete(frameStreams, stream)
if len(frameStreams) == 0 {
ResetFrameSlots()
maxFrameSlots.Store(defaultMaxInFlightFrames)
} else {
applyActiveFrameStreamLimitLocked()
}
frameStreamsMu.Unlock()
}
func applyActiveFrameStreamLimitLocked() {
combinedFPS := 0
for _, fps := range frameStreams {
if fps > 0 {
combinedFPS += fps
}
}
maxFrameSlots.Store(frameSlotLimitForFPS(combinedFPS))
}
func frameSlotLimitForFPS(fps int) int64 {
2026-06-07 00:05:35 -05:00
limit := defaultMaxInFlightFrames
switch {
case fps >= 180:
2026-07-30 00:22:08 -05:00
limit = 12
2026-06-07 00:05:35 -05:00
case fps >= 120:
2026-07-30 00:22:08 -05:00
limit = 8
case fps >= 60:
2026-06-07 00:05:35 -05:00
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)
}
}
}
return limit
2026-06-07 00:05:35 -05:00
}
func activeFrameSlotLimit() int64 {
if limit := maxFrameSlots.Load(); limit > 0 {
return limit
}
return defaultMaxInFlightFrames
}
2026-07-06 20:19:38 -05:00
func frameFlowSnapshot() (inFlight, limit int64, ackSeen bool, ackAge time.Duration) {
inFlight = inFlightFrames.Load()
limit = activeFrameSlotLimit()
ackSeen = frameAckSeen.Load()
if lastAck := lastAckNano.Load(); lastAck > 0 {
ackAge = time.Since(time.Unix(0, lastAck))
}
return inFlight, limit, ackSeen, ackAge
}