main f2d166b

vrr.go RawHistoryFolder

1package drm
2
3import (
4	"time"
5
6	"github.com/bnema/neferwl/internal/ports"
7)
8
9// Tearing, variable refresh and content type of frame commits.
10
11// probeAsync checks once whether async commits may carry IN_FENCE_FD. An
12// inactive CRTC refuses async flips: the probe waits until it is on.
13func (o *Output) probeAsync(r ports.Renderer) {
14	if o.asyncProbed || !o.tearing || o.off {
15		return
16	}
17	o.asyncProbed = true
18	r.UseTarget(o.back)
19	done, err := r.Render(ports.Scene{Background: "#000000"}, nil)
20	if err != nil {
21		return
22	}
23	req := &atomicReq{}
24	req.set(o.primary.id, o.primary.prop("FB_ID"), uint64(o.fbs[o.back]))
25	if done != nil {
26		defer done.Close()
27		o.fenceProp(req, o.primary, done)
28	}
29	err = o.k.commit(req, atomicTestOnly|flipAsyncFlag, 0)
30	// With CPU waits no fence is in a commit, async or not.
31	o.asyncFence = err == nil && (done != nil || o.cpuFences)
32	o.log.Info().Err(err).Str("connector", o.conn.name).Bool("async_fence", o.asyncFence).Msg("tearing probe")
33}
34
35// wantVRR is the VRR state the next frame commit sets: on while game (a
36// buffer is scanned out or a fullscreen window covers the output), off
37// after vrrHold without it (each toggle may flicker, so short breaks keep
38// it).
39func (o *Output) wantVRR(game bool) bool {
40	if o.vrrProp == 0 {
41		return false
42	}
43	o.vrrGame = game
44	if game {
45		o.composedSince = time.Time{}
46		return true
47	}
48	if o.composedSince.IsZero() {
49		o.composedSince = time.Now()
50	}
51	return o.vrrOn && time.Since(o.composedSince) <= vrrHold
52}
53
54// stateVRR is the VRR state of a commit without a new frame (cursor,
55// vrrOff timer): the last frame's. A shown buffer is not enough: it may
56// be a tiled window on the overlay plane.
57func (o *Output) stateVRR() bool { return o.wantVRR(o.vrrGame) }
58
59// contentProps changes the connector hint only when it differs from the applied value.
60func (o *Output) contentProps(req *atomicReq) {
61	if o.contentProp != 0 && o.contentWanted != o.contentValue {
62		req.set(o.conn.id, o.contentProp, o.contentWanted)
63	}
64}
65
66// wantContent chooses a content hint for the only visible fullscreen window.
67func (o *Output) wantContent(s ports.Scene, surfaces map[ports.WindowID]ports.SurfaceContent) {
68	o.contentWanted = o.contentValues[0]
69	var full *ports.SceneWindow
70	for i := range s.Windows {
71		w := &s.Windows[i]
72		if !s.Draws(*w) {
73			continue
74		}
75		if !w.Fullscreen || !covers(&s, w) || full != nil {
76			return
77		}
78		full = w
79	}
80	if full == nil {
81		return
82	}
83	switch surfaces[full.ID].ContentType {
84	case ports.ContentPhoto:
85		o.contentWanted = o.contentValues[2]
86	case ports.ContentVideo:
87		o.contentWanted = o.contentValues[3]
88	case ports.ContentGame:
89		o.contentWanted = o.contentValues[4]
90	}
91}
92
93// vrrHold is how long composition runs before VRR turns off.
94const vrrHold = 500 * time.Millisecond
95
96// setAsync logs when the output starts or stops tearing.
97func (o *Output) setAsync(on bool) {
98	if on != o.async {
99		o.async = on
100		o.log.Info().Bool("tearing", on).Str("connector", o.conn.name).Msg("tearing")
101	}
102}

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