~emersion/drmdb

8d220797622d7fa61a5d20af5a5c85b2e5927daa — Simon Ser 9 months ago f1d196c
Render node trees in templates
3 files changed, 248 insertions(+), 40 deletions(-)

M drmtree/drmtree.go
M public/device.html
M template.go
M drmtree/drmtree.go => drmtree/drmtree.go +51 -31
@@ 19,7 19,7 @@ type DriverVersion struct {
	Date  string `json:"date"`
}

func (ver *DriverVersion) String() string {
func (ver DriverVersion) String() string {
	return fmt.Sprintf("%v.%v.%v (%v)", ver.Major, ver.Minor, ver.Patch, ver.Date)
}



@@ 46,7 46,7 @@ type Kernel struct {
	Version string `json:"version"`
}

func (k *Kernel) String() string {
func (k Kernel) String() string {
	if k.SysName == "" {
		return "unknown kernel"
	}


@@ 395,6 395,37 @@ func (prop *Property) UnmarshalJSON(b []byte) error {
	return nil
}

func (prop Property) ValueString() string {
	val := prop.Data
	if val == nil {
		val = prop.Value
	}
	switch prop.Type {
	case drm.PropertyEnum:
		u := val.(uint64)
		entries := prop.Spec.(PropertySpecEnum)
		val = "<invalid>"
		for _, e := range entries {
			if e.Value == u {
				val = e.Name
				break
			}
		}
	case drm.PropertyBitmask:
		u := val.(uint64)
		entries := prop.Spec.(PropertySpecEnum)
		var names []string
		for _, e := range entries {
			bit := uint64(1 << e.Value)
			if u&bit != 0 {
				names = append(names, e.Name)
			}
		}
		val = "(" + strings.Join(names, " | ") + ")"
	}
	return fmt.Sprintf("%v", val)
}

type PropertyMap map[string]Property

func (m *PropertyMap) UnmarshalJSON(b []byte) error {


@@ 450,11 481,7 @@ func (m *PropertyMap) FormatTree(tf treefmt.Formatter) {
			s += " " + specStr
		}

		val := prop.Data
		if val == nil {
			val = prop.Value
		}
		switch val := val.(type) {
		switch val := prop.Data.(type) {
		case []PlaneInFormatsModifier:
			tf.Printf("%v", s)
			tfc := tf.NewChild()


@@ 472,30 499,7 @@ func (m *PropertyMap) FormatTree(tf treefmt.Formatter) {
				tfc.Printf("%v", fmt)
			}
		default:
			switch prop.Type {
			case drm.PropertyEnum:
				u := val.(uint64)
				entries := prop.Spec.(PropertySpecEnum)
				val = "<invalid>"
				for _, e := range entries {
					if e.Value == u {
						val = e.Name
						break
					}
				}
			case drm.PropertyBitmask:
				u := val.(uint64)
				entries := prop.Spec.(PropertySpecEnum)
				var names []string
				for _, e := range entries {
					bit := uint64(1 << e.Value)
					if u&bit != 0 {
						names = append(names, e.Name)
					}
				}
				val = "(" + strings.Join(names, " | ") + ")"
			}
			tf.Printf("%v = %v", s, val)
			tf.Printf("%v = %v", s, prop.ValueString())
		}
	}
}


@@ 512,6 516,10 @@ type Connector struct {
	Properties PropertyMap         `json:"properties"`
}

func (Connector) ObjectType() drm.ObjectType {
	return drm.ObjectConnector
}

func encoderIDsString(encs []drm.EncoderID) string {
	s := "{"
	for i, id := range encs {


@@ 554,6 562,10 @@ type Encoder struct {
	PossibleClones uint32          `json:"possible_clones"`
}

func (Encoder) ObjectType() drm.ObjectType {
	return drm.ObjectEncoder
}

func bitfieldString(v uint32) string {
	s := "{"
	first := true


@@ 587,6 599,10 @@ type CRTC struct {
	Properties PropertyMap `json:"properties"`
}

func (CRTC) ObjectType() drm.ObjectType {
	return drm.ObjectCRTC
}

func (crtc *CRTC) FormatTree(tf treefmt.Formatter) {
	tf.Printf("Object ID: %v", crtc.ID)
	tf.Printf("FB: %v", crtc.FB)


@@ 611,6 627,10 @@ type Plane struct {
	Properties    PropertyMap  `json:"properties"`
}

func (Plane) ObjectType() drm.ObjectType {
	return drm.ObjectPlane
}

func (plane *Plane) Type() drm.PlaneType {
	if t, ok := plane.Properties["type"]; ok {
		return drm.PlaneType(t.RawValue)

M public/device.html => public/device.html +188 -9
@@ 16,23 16,202 @@

<h2 id="tree">Latest snapshot</h2>

{{define "tree"}}
	<li>{{.Text}}
		{{if gt (len .Children) 0}}
		<ul>
			{{range .Children}}
			{{template "tree" .}}
{{define "formats"}}
<ul>
	{{range .}}
	<li>{{.}}</li>
	{{end}}
</ul>
{{end}}

{{define "in-formats"}}
<ul>
	{{range .}}
	<li>{{.Modifier}}
		{{template "formats" .Formats}}
	</li>
	{{end}}
</ul>
{{end}}

{{define "properties"}}
<li>Properties
	<ul>
		{{range $name, $value := .Properties}}
		<li>"<a href="/properties/{{printf "%d" $.ObjectType}}/{{$name}}">{{$name}}</a>"
			{{- if and .Immutable .Atomic}}
				(immutable, atomic)
			{{- else if .Immutable}}
				(immutable)
			{{- else if .Atomic}}
				(atomic)
			{{- end -}}
			: {{.Type}}
			{{with .Spec}}{{.}}{{end}}
			{{$typ := printf "%T" .Data}}
			{{if eq $typ "[]drmtree.PlaneInFormatsModifier"}}
			{{template "in-formats" .Data}}
			{{else if eq $typ "[]drm.Format"}}
			{{template "formats" .Data}}
			{{else}}
			= {{.ValueString}}
			{{end}}
		</ul>
		</li>
		{{end}}
	</ul>
</li>
{{end}}

{{define "connector"}}
<ul>
	<li>Object ID: {{.ID}}</li>
	<li>Type: {{.Type}}</li>
	<li>Encoders:
		{{"{" -}}
		{{- range $i, $enc := .Encoders -}}
			{{- if gt $i 0}}, {{end -}}
			<a href="#object-{{$enc}}">{{$enc}}</a>
		{{- end -}}
		{{"}"}}
	</li>
	{{template "properties" .}}
</ul>
{{end}}

{{define "encoder"}}
<ul>
	<li>Object ID: {{.ID}}</li>
	<li>Type: {{.Type}}</li>
	<li>CRTCs:
		{{"{" -}}
		{{- range $i, $value := bits .PossibleCRTCs -}}
			{{- if gt $i 0}}, {{end -}}
			<a href="#crtc-{{.}}">{{.}}</a>
		{{- end -}}
		{{"}"}}
	</li>
	<li>Clones:
		{{"{" -}}
		{{- range $i, $value := bits .PossibleClones -}}
			{{- if gt $i 0}}, {{end -}}
			<a href="#encoder-{{.}}">{{.}}</a>
		{{- end -}}
		{{"}"}}
	</li>
</ul>
{{end}}

{{define "crtc"}}
<ul>
	<li>Object ID: {{.ID}}</li>
	<li>Gamma size: {{.GammaSize}}</li>
	{{template "properties" .}}
</ul>
{{end}}

{{define "plane"}}
<ul>
	<li>Object ID: {{.ID}}</li>
	<li>CRTCs:
		{{"{" -}}
		{{- range $i, $value := bits .PossibleCRTCs -}}
			{{- if gt $i 0}}, {{end -}}
			<a href="#crtc-{{.}}">{{.}}</a>
		{{- end -}}
		{{"}"}}
	</li>
	<li>Formats:
		{{template "formats" .Formats}}
	</li>
	{{template "properties" .}}
</ul>
{{end}}

{{with .Node}}
<ul class="pre">
	{{range .Tree}}
	{{template "tree" .}}
	{{with .Driver}}
	<li id="driver">Driver:
		{{.Name}} ({{.Desc}}) version {{.Version}} on {{.Kernel}}
		<ul>
			{{range $name, $ok := .ClientCaps}}
			<li>
				DRM_CLIENT_CAP_{{$name}}
				{{if $ok}}supported{{else}}unsupported{{end}}
			</li>
			{{end}}
			{{range $name, $value := .Caps}}
			<li>
				DRM_CAP_{{$name}}
				{{if $value}}
				= {{$value}}
				{{else}}
				unsupported
				{{end}}
			</li>
			{{end}}
		</ul>
	</li>
	{{end}}

	{{with .Device}}
	<li id="device">Device:
		{{.BusType}} {{.BusID}}
	</li>
	{{end}}

	{{with .Connectors}}
	<li id="connectors">Connectors
		<ul>
			{{range $i, $conn := .}}
			<li id="object-{{.ID}}">Connector {{$i}}
				<span id="connector-{{$i}}"></span>
				{{template "connector" .}}
			</li>
			{{end}}
		</ul>
	</li>
	{{end}}

	{{with .Encoders}}
	<li id="encoders">Encoders
		<ul>
			{{range $i, $enc := .}}
			<li id="object-{{.ID}}">Encoder {{$i}}
				<span id="encoder-{{$i}}"></span>
				{{template "encoder" .}}
			</li>
			{{end}}
		</ul>
	</li>
	{{end}}

	{{with .CRTCs}}
	<li id="crtcs">CRTCs
		<ul>
			{{range $i, $crtc := .}}
			<li id="object-{{.ID}}">CRTC {{$i}}
				<span id="crtc-{{$i}}"></span>
				{{template "crtc" .}}
			</li>
			{{end}}
		</ul>
	</li>
	{{end}}

	{{with .Planes}}
	<li id="planes">Planes
		<ul>
			{{range $i, $plane := .}}
			<li id="object-{{.ID}}">Plane {{$i}}
				<span id="plane-{{$i}}"></span>
				{{template "plane" .}}
			</li>
			{{end}}
		</ul>
	</li>
	{{end}}
</ul>
{{end}}

<h2 id="alt-devices">Other snapshots</h2>


M template.go => template.go +9 -0
@@ 37,6 37,15 @@ func loadTemplates() (*tmpl, error) {
		"drmModifierHex": func(mod drm.Modifier) string {
			return fmt.Sprintf("0x%X", uint64(mod))
		},
		"bits": func(mask uint32) []int{
			var l []int
			for i := 0; i < 32; i++ {
				if mask & (uint32(1) << uint(i)) != 0 {
					l = append(l, i)
				}
			}
			return l
		},
	}).ParseGlob("public/*.html")

	return &tmpl{t}, err