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		req.set(o.primary.id, o.primary.prop("IN_FENCE_FD"), uint64(done.Fd()))
28	}
29	err = o.k.commit(req, atomicTestOnly|flipAsyncFlag, 0)
30	o.asyncFence = err == nil && done != nil
31	o.log.Info().Err(err).Str("connector", o.conn.name).Bool("async_fence", o.asyncFence).Msg("tearing probe")
32}
33
34// wantVRR is the VRR state the next frame commit sets: on while game (a
35// buffer is scanned out or a fullscreen window covers the output), off
36// after vrrHold without it (each toggle may flicker, so short breaks keep
37// it).
38func (o *Output) wantVRR(game bool) bool {
39	if o.vrrProp == 0 {
40		return false
41	}
42	o.vrrGame = game
43	if game {
44		o.composedSince = time.Time{}
45		return true
46	}
47	if o.composedSince.IsZero() {
48		o.composedSince = time.Now()
49	}
50	return o.vrrOn && time.Since(o.composedSince) <= vrrHold
51}
52
53// stateVRR is the VRR state of a commit without a new frame (cursor,
54// vrrOff timer): the last frame's. A shown buffer is not enough: it may
55// be a tiled window on the overlay plane.
56func (o *Output) stateVRR() bool { return o.wantVRR(o.vrrGame) }
57
58// contentProps changes the connector hint only when it differs from the applied value.
59func (o *Output) contentProps(req *atomicReq) {
60	if o.contentProp != 0 && o.contentWanted != o.contentValue {
61		req.set(o.conn.id, o.contentProp, o.contentWanted)
62	}
63}
64
65// wantContent chooses a content hint for the only visible fullscreen window.
66func (o *Output) wantContent(s ports.Scene, surfaces map[ports.WindowID]ports.SurfaceContent) {
67	o.contentWanted = o.contentValues[0]
68	var full *ports.SceneWindow
69	for i := range s.Windows {
70		w := &s.Windows[i]
71		if w.Hidden || w.Rect.W <= 0 || w.Rect.H <= 0 {
72			continue
73		}
74		if !w.Fullscreen || !covers(&s, w) || full != nil {
75			return
76		}
77		full = w
78	}
79	if full == nil {
80		return
81	}
82	switch surfaces[full.ID].ContentType {
83	case ports.ContentPhoto:
84		o.contentWanted = o.contentValues[2]
85	case ports.ContentVideo:
86		o.contentWanted = o.contentValues[3]
87	case ports.ContentGame:
88		o.contentWanted = o.contentValues[4]
89	}
90}
91
92// vrrHold is how long composition runs before VRR turns off.
93const vrrHold = 500 * time.Millisecond
94
95// setAsync logs when the output starts or stops tearing.
96func (o *Output) setAsync(on bool) {
97	if on != o.async {
98		o.async = on
99		o.log.Info().Bool("tearing", on).Str("connector", o.conn.name).Msg("tearing")
100	}
101}

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