main f2d166b

state_schedule.go RawHistoryFolder

1package drm
2
3import "time"
4
5// State commit scheduling: a CRTC takes one atomic commit per vblank, so a
6// commit carrying only state (cursor move, VRR toggle, content type) holds
7// the next frame until it lands. Committed as soon as the pointer moves, it
8// pushes a video frame that arrives later in the same refresh period to the
9// following vblank: a visible stutter on every cursor move over the output
10// or across to another one.
11//
12// So a state change waits until stateLead before the next vblank. A frame
13// committed before then carries it (one commit, no lost vblank); otherwise
14// the state commits alone and still lands on that vblank, so the cursor is
15// never later than it would have been.
16//
17// Under VRR there is no fixed vblank to aim at: state commits at once (a
18// game's cursor rides on its frames, see cursorWaits).
19
20// stateLeadMax is how long before the vblank a deferred state commit is
21// made: enough for the kernel to program the planes for that vblank.
22const stateLeadMax = 1500 * time.Microsecond
23
24// vblankStale is how old the last vblank may be to predict the next one: a
25// longer idle period lets the nominal period drift from the panel's.
26const vblankStale = 250 * time.Millisecond
27
28// stateLead is stateLeadMax, at most a quarter of period.
29func stateLead(period time.Duration) time.Duration { return min(stateLeadMax, period/4) }
30
31// stateDelay is how long a state change made at now (CLOCK_MONOTONIC)
32// waits before its own commit: until stateLead before the next vblank, 0
33// when that point has passed or no vblank can be predicted (VRR, no recent
34// flip).
35func (o *Output) stateDelay(now time.Duration) time.Duration {
36	period := o.refreshPeriod()
37	last := o.lastVblankAt
38	if period <= 0 || last <= 0 || now < last || now-last > vblankStale {
39		return 0
40	}
41	next := last + ((now-last)/period+1)*period
42	return max(0, next-stateLead(period)-now)
43}
44
45// stateChanged reports whether a state commit would change anything:
46// cursor, VRR or content type differ from what KMS holds.
47func (o *Output) stateChanged(vrr bool) bool {
48	if o.cursor != nil && o.cursor.desired() != o.cursor.applied {
49		return true
50	}
51	if vrr != o.vrrOn {
52		return true
53	}
54	return o.contentProp != 0 && o.contentWanted != o.contentValue
55}
56
57// stateDue reports whether the state commit may go now. The first call
58// for a change fixes its time (stateAt) and later calls keep it, so a
59// timer that fires late never pushes the commit by another period.
60func (o *Output) stateDue(now time.Time, mono time.Duration) bool {
61	if o.stateAt.IsZero() {
62		o.stateAt = now.Add(o.stateDelay(mono))
63	}
64	if now.Before(o.stateAt) {
65		return false
66	}
67	o.stateAt = time.Time{}
68	return true
69}
70
71// noteVblank records the vblank of a completed vsynced commit (frame or
72// state). A tearing flip's timestamp is not a vblank.
73func (o *Output) noteVblank(f pendingFrame, when time.Duration) {
74	if f.async || when <= 0 {
75		return
76	}
77	o.lastVblankAt = when
78}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 25

Tags 10

↑↓ moveenter openesc close