~emersion/drmdb

e3e3179febefc9275824230119bb8b8f8a7132b5 — Simon Ser 2 years ago 3ea7677
Add formats page
5 files changed, 147 insertions(+), 5 deletions(-)

M drmtree/drmtree.go
M public/assets/style.css
A public/formats.html
M public/index.html
M server.go
M drmtree/drmtree.go => drmtree/drmtree.go +20 -0
@@ 590,6 590,26 @@ type Plane struct {
	Properties    PropertyMap  `json:"properties"`
}

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

func (plane *Plane) InFormats() []PlaneInFormatsModifier {
	if inFormats, ok := plane.Properties["IN_FORMATS"]; ok {
		return inFormats.Data.([]PlaneInFormatsModifier)
	}

	return []PlaneInFormatsModifier{
		{
			Modifier: 0, // linear
			Formats: plane.Formats,
		},
	}
}

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

M public/assets/style.css => public/assets/style.css +1 -4
@@ 31,13 31,10 @@ th, td {
    background-clip: padding-box;
}

th {
thead {
    position: sticky;
    top: 0;
    background-color: #888;
}

th {
    color: white;
}


A public/formats.html => public/formats.html +44 -0
@@ 0,0 1,44 @@
{{template "head" "Formats"}}

<h1>DRM database formats</h1>

<p><a href="/">Back to index</a></p>

<h2 id="in-formats">Input formats</h2>

<table>
    <thead>
        <tr>
            <th rowspan="2">Modifier</th>
            <th rowspan="2">Format</th>
            <th colspan="{{len .Planes}}">Planes</th>
            <th colspan="{{len .Drivers}}">Drivers</th>
        </tr>
        <tr>
            {{range $plane, $_ := .Planes}}
            <th>{{$plane.String}}</th>
            {{end}}
            {{range $drv, $_ := .Drivers}}
            <th>{{$drv}}</th>
            {{end}}
        </tr>
    </thead>
    <tbody>
        {{$total := .Total}}
        {{$planes := .Planes}}
        {{$drivers := .Drivers}}
        {{range .Formats}}
        <tr>
            {{$row := .}}
            <td class="pre">{{.Modifier}}</td>
            <td class="pre">{{.Format}}</td>
            {{range $plane, $_ := $planes}}
            <td>{{pct (index $row.Planes $plane) $total}}</td>
            {{end}}
            {{range $drv, $_ := $drivers}}
            <td>{{pct (index $row.Drivers $drv) $total}}</td>
            {{end}}
        </tr>
        {{end}}
    </tbody>
</table>

M public/index.html => public/index.html +1 -0
@@ 10,6 10,7 @@ used to keep track of GPUs and DRM driver features support.</p>
    <li><a href="/devices">Devices</a></li>
    <li><a href="/capabilities">Capabilities</a></li>
    <li><a href="/properties">Properties</a></li>
    <li><a href="/formats">Formats</a></li>
</ul>

<h2>Contributing</h2>

M server.go => server.go +81 -1
@@ 178,6 178,13 @@ func loadPCIIDs() (vendors map[uint16]string, devices map[uint32]string, err err
	return vendors, devices, db.Close()
}

func modifierString(mod drm.Modifier) string {
	if mod == 0 {
		return "DRM_FORMAT_MOD_LINEAR"
	}
	return fmt.Sprintf("%v modifier (0x%X)", mod.Vendor(), mod)
}

func New() *echo.Echo {
	e := echo.New()



@@ 186,7 193,11 @@ func New() *echo.Echo {
	}

	e.Renderer = &Template{
		t: template.Must(template.ParseGlob("public/*.html")),
		t: template.Must(template.New("drmdb").Funcs(template.FuncMap{
			"pct": func (num, tot int) string {
				return fmt.Sprintf("%v%%", int(100 * float32(num) / float32(tot)))
			},
		}).ParseGlob("public/*.html")),
	}

	pciVendors, pciDevices, err := loadPCIIDs()


@@ 399,6 410,75 @@ func New() *echo.Echo {
		}{drivers, props})
	})

	e.GET("/formats", func(c echo.Context) error {
		type modifierAndFormat struct {
			mod drm.Modifier
			fmt drm.Format
		}
		type formatData struct {
			Modifier string
			Format drm.Format
			Planes map[drm.PlaneType]int
			Drivers map[string]int
		}

		total := 0
		planes := make(map[drm.PlaneType]bool)
		drivers := make(map[string]bool)
		formats := make(map[modifierAndFormat]formatData)
		err := walkLatest(walkLatestDevice, func(k string, n *drmtree.Node) error {
			total++
			drivers[n.Driver.Name] = true

			planeFormats := make(map[drm.PlaneType]map[modifierAndFormat]bool)
			driverFormats := make(map[modifierAndFormat]bool)

			for _, plane := range n.Planes {
				planes[plane.Type()] = true

				if _, ok := planeFormats[plane.Type()]; !ok {
					planeFormats[plane.Type()] = make(map[modifierAndFormat]bool)
				}

				inFormats := plane.InFormats()
				for _, mod := range inFormats {
					for _, fmt := range mod.Formats {
						k := modifierAndFormat{mod.Modifier, fmt}
						if _, ok := formats[k]; !ok {
							formats[k] = formatData{
								Modifier: modifierString(mod.Modifier),
								Format: fmt,
								Planes: make(map[drm.PlaneType]int),
								Drivers: make(map[string]int),
							}
						}

						if !planeFormats[plane.Type()][k] {
							formats[k].Planes[plane.Type()]++
							planeFormats[plane.Type()][k] = true
						}

						if !driverFormats[k] {
							formats[k].Drivers[n.Driver.Name]++
							driverFormats[k] = true
						}
					}
				}
			}
			return nil
		})
		if err != nil {
			return err
		}

		return c.Render(http.StatusOK, "formats.html", struct {
			Total int
			Planes map[drm.PlaneType]bool
			Drivers map[string]bool
			Formats map[modifierAndFormat]formatData
		}{total, planes, drivers, formats})
	})

	e.Static("/assets", "public/assets")

	return e