blob: 181612b3203562360b5ccbde6d441ac474a96c63 [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/interval"
"android.googlesource.com/platform/tools/gpu/service"
"android.googlesource.com/platform/tools/gpu/service/path"
"android.googlesource.com/platform/tools/gpu/task"
"github.com/google/gxui"
"github.com/google/gxui/math"
)
type MemoryAdapter struct {
gxui.AdapterBase
appCtx *ApplicationContext
path *path.MemoryRange
bytesPerLine uint64
dataType DataType
}
func CreateMemoryAdapter(appCtx *ApplicationContext) *MemoryAdapter {
return &MemoryAdapter{
appCtx: appCtx,
bytesPerLine: 32,
dataType: U8(0),
}
}
func (a *MemoryAdapter) Update(p *path.MemoryRange) {
a.path = p
a.DataReplaced()
}
func (a *MemoryAdapter) IndexOfAddress(addr uint64) int {
if a.path != nil {
return int(addr/a.bytesPerLine - a.path.Address)
} else {
return 0
}
}
func (a *MemoryAdapter) AddressAtIndex(index int) uint64 {
if a.path != nil {
return a.path.Address + uint64(index)*a.bytesPerLine
} else {
return 0
}
}
func (a *MemoryAdapter) SetDataType(dataType DataType) {
a.dataType = dataType
a.DataReplaced()
}
func (a *MemoryAdapter) Size(theme gxui.Theme) math.Size {
return math.Size{W: math.MaxSize.W, H: 14}
}
func (a *MemoryAdapter) Count() int {
if a.path != nil {
return 10000 //Who knows?
} else {
return 0
}
}
func (a *MemoryAdapter) ItemAt(index int) gxui.AdapterItem {
return a.AddressAtIndex(index)
}
func (a *MemoryAdapter) ItemIndex(item gxui.AdapterItem) int {
addr := item.(uint64)
return a.IndexOfAddress(addr)
}
func (a *MemoryAdapter) Create(theme gxui.Theme, index int) gxui.Control {
ll := theme.CreateLinearLayout()
ll.SetDirection(gxui.LeftToRight)
base, size := a.AddressAtIndex(index), a.bytesPerLine
t := task.New()
update := func() {
p := a.path.Clone().(*path.MemoryRange)
p.Address = base
p.Size = size
t.Run(requestMemory{a.appCtx, p, func(info service.MemoryInfo) {
ll.RemoveAll()
ll.AddChild(createLabel(a.appCtx, fmt.Sprintf("%.16x ", base), LINE_NUMBER_COLOR))
offset := uint64(0)
data := info.Data
dataType := a.dataType
dataTypeSize := dataType.SizeBytes()
for len(data) >= dataTypeSize {
switch {
case interval.Contains(&info.Writes, offset):
ll.AddChild(createMonospaceLabel(a.appCtx, dataType.Read(data).String()+" ", WRITE_MEMORY_COLOR))
case interval.Contains(&info.Reads, offset):
ll.AddChild(createMonospaceLabel(a.appCtx, dataType.Read(data).String()+" ", READ_MEMORY_COLOR))
case interval.Contains(&info.Observed, offset):
ll.AddChild(createMonospaceLabel(a.appCtx, dataType.Read(data).String()+" ", STALE_MEMORY_COLOR))
default:
ll.AddChild(createMonospaceLabel(a.appCtx, dataType.Unknown()+" ", STALE_MEMORY_COLOR))
}
offset += uint64(dataTypeSize)
data = data[dataTypeSize:]
}
}})
}
ll.OnAttach(update)
ll.OnDetach(t.Cancel)
return ll
}