package drmdb
import (
"sort"
"git.sr.ht/~emersion/drmdb/database"
"git.sr.ht/~emersion/drmdb/drmtree"
"git.sr.ht/~emersion/go-drm"
"github.com/mcuadros/go-version"
)
func walkProps(props drmtree.PropertyMap, obj drm.AnyID, f func(drm.AnyID, string, *drmtree.Property) error) error {
for name, prop := range props {
if err := f(obj, name, &prop); err != nil {
return err
}
}
return nil
}
func walkNodeProps(n *drmtree.Node, f func(drm.AnyID, string, *drmtree.Property) error) error {
for _, conn := range n.Connectors {
if err := walkProps(conn.Properties, conn.ID, f); err != nil {
return err
}
}
for _, crtc := range n.CRTCs {
if err := walkProps(crtc.Properties, crtc.ID, f); err != nil {
return err
}
}
for _, plane := range n.Planes {
if err := walkProps(plane.Properties, plane.ID, f); err != nil {
return err
}
}
return nil
}
func driverLess(a *drmtree.Driver, b *drmtree.Driver) bool {
if a.Version.Less(&b.Version) {
return true
}
// Linux is the upstream
if b.Kernel.SysName == "Linux" && a.Kernel.SysName != "Linux" {
return true
}
return version.Compare(a.Kernel.Release, b.Kernel.Release, "<")
}
type walkLatestField int
const (
walkLatestDriver walkLatestField = iota
walkLatestDevice
)
func walkLatest(db *database.DB, f walkLatestField, fn func(k string, n *drmtree.Node) error) error {
type node struct {
k string
n *drmtree.Node
}
latest := make(map[string]node)
err := db.Walk(func(k string, n *drmtree.Node) error {
var latestKey string
switch f {
case walkLatestDriver:
latestKey = n.Driver.Name
case walkLatestDevice:
latestKey = n.Device.BusID()
}
if latestKey == "" {
return nil
}
other, ok := latest[latestKey]
if ok && driverLess(n.Driver, other.n.Driver) {
return nil
}
latest[latestKey] = node{k, n}
return nil
})
if err != nil {
return err
}
keys := make([]string, 0, len(latest))
for k := range latest {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
n := latest[k]
if err := fn(n.k, n.n); err != nil {
return err
}
}
return nil
}