blob: d8387d0c0cb7429f4af800571ea0d7f3b22ecf4c [file] [log] [blame]
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package client
import (
"fmt"
"android.googlesource.com/platform/tools/gpu/atom"
"github.com/google/gxui"
)
type atomItem struct {
atomID atom.ID
}
// atomTreeNode is a gxui.TreeNode representing a single atom.
// It has the item of type atomItem.
type atomTreeNode struct {
ctx *commandAdapterCtx
item atomItem
}
func (n atomTreeNode) Count() int {
atom := n.ctx.atoms[n.item.atomID]
observations := atom.Observations()
return len(observations.Reads) + len(observations.Writes)
}
func (n atomTreeNode) NodeAt(index int) gxui.TreeNode {
atom := n.ctx.atoms[n.item.atomID]
observations := atom.Observations()
if index < len(observations.Reads) {
return observationTreeNode{
ctx: n.ctx,
item: observationItem{
atomID: n.item.atomID,
isRead: true,
index: index,
},
}
} else {
return observationTreeNode{
ctx: n.ctx,
item: observationItem{
atomID: n.item.atomID,
isRead: false,
index: index - len(observations.Reads),
},
}
}
}
func (n atomTreeNode) Item() gxui.AdapterItem {
return n.item
}
func (n atomTreeNode) ItemIndex(item gxui.AdapterItem) int {
if i := item.(observationItem); i.isRead {
return i.index
} else {
atom := n.ctx.atoms[n.item.atomID]
observations := atom.Observations()
return len(observations.Reads) + i.index
}
}
func (n atomTreeNode) Create(t gxui.Theme) gxui.Control {
p := n.ctx.capture.Atoms().Index(uint64(n.item.atomID))
a := n.ctx.atoms[p.Index].(*Atom)
layout := t.CreateLinearLayout()
layout.SetDirection(gxui.LeftToRight)
layout.AddChild(createLabel(n.ctx.appCtx, fmt.Sprintf("%.6d ", p.Index), LINE_NUMBER_COLOR))
if ns, ok := n.ctx.timings.AtomDuration(n.item.atomID); ok {
timeLbl := t.CreateLabel()
milliseconds := float64(ns) / 1000000.
timeLbl.SetText(fmt.Sprintf("%6.3f ms ", milliseconds))
switch {
case milliseconds >= 1.0:
timeLbl.SetColor(gxui.ColorFromHex(0xFFFC19 + 0xFF<<24))
case milliseconds >= 5.0:
timeLbl.SetColor(gxui.ColorFromHex(0xD21212 + 0xFF<<24))
}
layout.AddChild(timeLbl)
}
nameLbl := createLabel(n.ctx.appCtx, atom.MetadataOf(a).DisplayName, COMMAND_COLOR)
layout.AddChild(nameLbl)
layout.AddChild(createLabel(n.ctx.appCtx, "(", CODE_COLOR))
needcomma := false
for i := 0; i < a.ParameterCount(); i++ {
f, v := a.Parameter(i)
if c := createField(n.ctx.appCtx, p.Field(f.Name()), f.Type, v); c != nil {
if needcomma {
layout.AddChild(createLabel(n.ctx.appCtx, ", ", CODE_COLOR))
}
layout.AddChild(c)
needcomma = true
}
}
layout.AddChild(createLabel(n.ctx.appCtx, ")", CODE_COLOR))
if f, v := a.Result(); f != nil {
layout.AddChild(createLabel(n.ctx.appCtx, " -> ", COMMAND_COLOR))
if c := createField(n.ctx.appCtx, p.Field(f.Name()), f.Type, v); c != nil {
layout.AddChild(c)
needcomma = true
}
}
return layout
}