v0.4.0 b6be3a8

edid_test.go RawHistoryFolder

1package drm
2
3import (
4	"math"
5	"testing"
6)
7
8func TestEDIDHDR(t *testing.T) {
9	d := make([]byte, 256)
10	copy(d, "\x00\xff\xff\xff\xff\xff\xff\x00")
11	d[20] = 0xb0 // digital, 10 bits per color
12	d[25], d[26] = 0b_10_01_11_00, 0b_01_11_10_00
13	d[27], d[28] = 128, 64
14	d[29], d[30] = 32, 16
15	d[31], d[32] = 8, 4
16	d[33], d[34] = 2, 1
17	d[126] = 1
18	d[128], d[130] = 2, 15
19	// CTA extended colorimetry: BT2020RGB + BT2020YCC.
20	copy(d[132:], []byte{0xe3, 5, 0xc0, 0})
21	// EOTF SDR, PQ, HLG; static type 1; max 200, average 100, min 200/100.
22	copy(d[136:], []byte{0xe6, 6, 0x0d, 1, 64, 32, 255})
23	m := parseEDID(d)
24	if m.BitsPerColor != 10 || !m.HDR.SDR || !m.HDR.PQ || !m.HDR.HLG || !m.HDR.StaticType1 || !m.HDR.BT2020RGB || !m.HDR.BT2020YCC {
25		t.Fatalf("%+v", m)
26	}
27	if m.Chromaticity.RedX != float64(128*4+2)/1024 || m.Chromaticity.GreenY != float64(16*4)/1024 || m.Chromaticity.WhiteY != float64(1*4)/1024 {
28		t.Fatalf("chromaticity: %+v", m.Chromaticity)
29	}
30	if math.Abs(m.HDR.MaxLuminance-200) > 1e-9 || math.Abs(m.HDR.MaxFrameAverage-100) > 1e-9 || math.Abs(m.HDR.MinLuminance-2) > 1e-9 {
31		t.Fatalf("luminances: %+v", m.HDR)
32	}
33	for _, n := range []int{0, 7, 127, 128, 129, 255} {
34		got := parseEDID(d[:n])
35		if got.HDR.PQ {
36			t.Fatalf("truncated %d: %+v", n, got)
37		}
38	}
39	d[132] = 0xff // block exceeds DTD boundary
40	if parseEDID(d).HDR.PQ {
41		t.Fatal("parsed malformed block")
42	}
43	d[132] = 0xe3
44	d[130] = 3 // invalid CTA offset
45	if parseEDID(d).HDR.PQ {
46		t.Fatal("parsed invalid CTA offset")
47	}
48	d[130] = 15
49	d[136] = 0xe2 // HDR payload without mandatory descriptor byte
50	if parseEDID(d).HDR.PQ {
51		t.Fatal("parsed truncated HDR payload")
52	}
53	d[20] = 0 // analog input cannot specify digital bit depth
54	if parseEDID(d).BitsPerColor != 0 {
55		t.Fatal("analog input has bit depth")
56	}
57}
58
59func TestDetectHDR(t *testing.T) {
60	m := Monitor{HDR: HDRMetadata{PQ: true, BT2020RGB: true, StaticType1: true}}
61	p := connectorHDRProps{Metadata: 1, Colorspace: 2, MaxBPC: 3, HasDefault: true}
62	cases := []struct {
63		name   string
64		m      Monitor
65		p      connectorHDRProps
66		reason string
67	}{
68		{"ready", m, p, ""},
69		{"no PQ", Monitor{HDR: HDRMetadata{BT2020RGB: true, StaticType1: true}}, p, "edid: no PQ"},
70		{"no RGB", Monitor{HDR: HDRMetadata{PQ: true, StaticType1: true}}, p, "edid: no BT2020RGB"},
71		{"no type 1", Monitor{HDR: HDRMetadata{PQ: true, BT2020RGB: true}}, p, "edid: no static metadata type 1"},
72		{"no metadata", m, connectorHDRProps{Colorspace: 2, MaxBPC: 3, HasDefault: true}, "connector: no HDR_OUTPUT_METADATA"},
73		{"no colorspace", m, connectorHDRProps{Metadata: 1, MaxBPC: 3}, "connector: no BT2020_RGB Colorspace"},
74		{"no bpc", m, connectorHDRProps{Metadata: 1, Colorspace: 2, HasDefault: true}, "connector: max bpc below 10"},
75	}
76	for _, tt := range cases {
77		t.Run(tt.name, func(t *testing.T) {
78			c := detectHDR(tt.m, tt.p)
79			if c.Capable != (tt.reason == "") || c.Reason != tt.reason {
80				t.Fatalf("%+v", c)
81			}
82		})
83	}
84}

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