2026-04-08 14:14:09 -05:00
|
|
|
package capture
|
|
|
|
|
|
|
|
|
|
import (
|
2026-06-07 00:05:35 -05:00
|
|
|
"os"
|
|
|
|
|
"strconv"
|
|
|
|
|
"strings"
|
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
|
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
|
|
|
|
|
}
|
|
|
|
|
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) {
|
|
|
|
|
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
|
|
|
|
|
}
|