fix(drm): turn VRR off on time when a composed screen stops changing
- commit
- 19dda7cecf62f7fdeb0d37311b0491baa5832ee5
- author
- brice · · 2026-09-25 18:03 UTC
- parent
- cdcafdb
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
1 file · +8 -4
M internal/adapters/drm/output.go +8 -4
| @@ -293,9 +293,17 @@ func (o *Output) Run(ctx context.Context, newRenderer func(w, h int) (ports.Rend | |||
| 293 | 293 | if o.unsent.Output != "" { | |
| 294 | 294 | retry = time.After(time.Millisecond) | |
| 295 | 295 | } | |
| 296 | + | // A composed screen that stopped changing still drops VRR on time. | |
| 297 | + | var vrrOff <-chan time.Time | |
| 298 | + | if o.vrrOn && !o.composedSince.IsZero() { | |
| 299 | + | vrrOff = time.After(max(0, vrrHold-time.Since(o.composedSince))) | |
| 300 | + | } | |
| 296 | 301 | select { | |
| 297 | 302 | case <-retry: | |
| 298 | 303 | continue | |
| 304 | + | case <-vrrOff: | |
| 305 | + | o.setVRR(false) | |
| 306 | + | continue | |
| 299 | 307 | case <-ctx.Done(): | |
| 300 | 308 | return nil | |
| 301 | 309 | case on := <-active: | |
| @@ -365,10 +373,6 @@ func (o *Output) Run(ctx context.Context, newRenderer func(w, h int) (ports.Rend | |||
| 365 | 373 | dirty = dirty || scene.Shows(c.ID) | |
| 366 | 374 | case <-stats.C: | |
| 367 | 375 | o.dropClientFBs(time.Now(), false) | |
| 368 | - | // A composed screen that stopped changing still drops VRR. | |
| 369 | - | if !o.composedSince.IsZero() && time.Since(o.composedSince) > vrrHold { | |
| 370 | - | o.setVRR(false) | |
| 371 | - | } | |
| 372 | 376 | ev := o.log.Info().Int("frames", frame).Int("flips", o.flips) | |
| 373 | 377 | if o.cursor != nil { | |
| 374 | 378 | cs := o.cursor.TakeStats() | |
| @@ -293,9 +293,17 @@ func (o *Output) Run(ctx context.Context, newRenderer func(w, h int) (ports.Rend | |||||
| 293 | if o.unsent.Output != "" { | 293 | if o.unsent.Output != "" { | ||
| 294 | retry = time.After(time.Millisecond) | 294 | retry = time.After(time.Millisecond) | ||
| 295 | } | 295 | } | ||
| 296 | + | // A composed screen that stopped changing still drops VRR on time. | |||
| 297 | + | var vrrOff <-chan time.Time | |||
| 298 | + | if o.vrrOn && !o.composedSince.IsZero() { | |||
| 299 | + | vrrOff = time.After(max(0, vrrHold-time.Since(o.composedSince))) | |||
| 300 | + | } | |||
| 296 | select { | 301 | select { | ||
| 297 | case <-retry: | 302 | case <-retry: | ||
| 298 | continue | 303 | continue | ||
| 304 | + | case <-vrrOff: | |||
| 305 | + | o.setVRR(false) | |||
| 306 | + | continue | |||
| 299 | case <-ctx.Done(): | 307 | case <-ctx.Done(): | ||
| 300 | return nil | 308 | return nil | ||
| 301 | case on := <-active: | 309 | case on := <-active: | ||
| @@ -365,10 +373,6 @@ func (o *Output) Run(ctx context.Context, newRenderer func(w, h int) (ports.Rend | |||||
| 365 | dirty = dirty || scene.Shows(c.ID) | 373 | dirty = dirty || scene.Shows(c.ID) | ||
| 366 | case <-stats.C: | 374 | case <-stats.C: | ||
| 367 | o.dropClientFBs(time.Now(), false) | 375 | o.dropClientFBs(time.Now(), false) | ||
| 368 | - | // A composed screen that stopped changing still drops VRR. | |||
| 369 | - | if !o.composedSince.IsZero() && time.Since(o.composedSince) > vrrHold { | |||
| 370 | - | o.setVRR(false) | |||
| 371 | - | } | |||
| 372 | ev := o.log.Info().Int("frames", frame).Int("flips", o.flips) | 376 | ev := o.log.Info().Int("frames", frame).Int("flips", o.flips) | ||
| 373 | if o.cursor != nil { | 377 | if o.cursor != nil { | ||
| 374 | cs := o.cursor.TakeStats() | 378 | cs := o.cursor.TakeStats() | ||