mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-06 18:05:35 +00:00
io/profile: [API] delete package
It was a design mistake to make profiling data available to programs. Rather, profiling should either be a user-configurable debug overlay, reported through runtime/trace, or both. This change drops the io/profile package because we're about to overhaul event routing. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+2
-14
@@ -21,7 +21,6 @@ import (
|
|||||||
"gioui.org/io/event"
|
"gioui.org/io/event"
|
||||||
"gioui.org/io/key"
|
"gioui.org/io/key"
|
||||||
"gioui.org/io/pointer"
|
"gioui.org/io/pointer"
|
||||||
"gioui.org/io/profile"
|
|
||||||
"gioui.org/io/router"
|
"gioui.org/io/router"
|
||||||
"gioui.org/io/system"
|
"gioui.org/io/system"
|
||||||
"gioui.org/layout"
|
"gioui.org/layout"
|
||||||
@@ -308,7 +307,7 @@ func (w *Window) frame(frame *op.Ops, viewport image.Point) error {
|
|||||||
return w.gpu.Frame(frame, target, viewport)
|
return w.gpu.Frame(frame, target, viewport)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) processFrame(d driver, frameStart time.Time) {
|
func (w *Window) processFrame(d driver) {
|
||||||
for k := range w.semantic.ids {
|
for k := range w.semantic.ids {
|
||||||
delete(w.semantic.ids, k)
|
delete(w.semantic.ids, k)
|
||||||
}
|
}
|
||||||
@@ -336,13 +335,6 @@ func (w *Window) processFrame(d driver, frameStart time.Time) {
|
|||||||
w.imeState = newState
|
w.imeState = newState
|
||||||
d.EditorStateChanged(oldState, newState)
|
d.EditorStateChanged(oldState, newState)
|
||||||
}
|
}
|
||||||
if q.Profiling() && w.gpu != nil {
|
|
||||||
frameDur := time.Since(frameStart)
|
|
||||||
frameDur = frameDur.Truncate(100 * time.Microsecond)
|
|
||||||
quantum := 100 * time.Microsecond
|
|
||||||
timings := fmt.Sprintf("tot:%7s %s", frameDur.Round(quantum), w.gpu.Profile())
|
|
||||||
q.Queue(profile.Event{Timings: timings})
|
|
||||||
}
|
|
||||||
if t, ok := q.WakeupTime(); ok {
|
if t, ok := q.WakeupTime(); ok {
|
||||||
w.setNextFrame(t)
|
w.setNextFrame(t)
|
||||||
}
|
}
|
||||||
@@ -844,10 +836,6 @@ func (w *Window) processEvent(d driver, e event.Event) bool {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
w.metric = e2.Metric
|
w.metric = e2.Metric
|
||||||
var frameStart time.Time
|
|
||||||
if w.queue.q.Profiling() {
|
|
||||||
frameStart = time.Now()
|
|
||||||
}
|
|
||||||
w.hasNextFrame = false
|
w.hasNextFrame = false
|
||||||
e2.Frame = w.update
|
e2.Frame = w.update
|
||||||
e2.Queue = &w.queue
|
e2.Queue = &w.queue
|
||||||
@@ -891,7 +879,7 @@ func (w *Window) processEvent(d driver, e event.Event) bool {
|
|||||||
close(w.destroy)
|
close(w.destroy)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
w.processFrame(d, frameStart)
|
w.processFrame(d)
|
||||||
w.updateCursor(d)
|
w.updateCursor(d)
|
||||||
case system.DestroyEvent:
|
case system.DestroyEvent:
|
||||||
w.destroyGPU()
|
w.destroyGPU()
|
||||||
|
|||||||
+3
-12
@@ -93,7 +93,6 @@ type compute struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
timers struct {
|
timers struct {
|
||||||
profile string
|
|
||||||
t *timers
|
t *timers
|
||||||
compact *timer
|
compact *timer
|
||||||
render *timer
|
render *timer
|
||||||
@@ -176,7 +175,6 @@ type materialUniforms struct {
|
|||||||
|
|
||||||
type collector struct {
|
type collector struct {
|
||||||
hasher maphash.Hash
|
hasher maphash.Hash
|
||||||
profile bool
|
|
||||||
reader ops.Reader
|
reader ops.Reader
|
||||||
states []f32.Affine2D
|
states []f32.Affine2D
|
||||||
clear bool
|
clear bool
|
||||||
@@ -597,7 +595,7 @@ func (g *compute) frame(target RenderTarget) error {
|
|||||||
defer g.ctx.EndFrame()
|
defer g.ctx.EndFrame()
|
||||||
|
|
||||||
t := &g.timers
|
t := &g.timers
|
||||||
if g.collector.profile && t.t == nil && g.ctx.Caps().Features.Has(driver.FeatureTimers) {
|
if false && t.t == nil && g.ctx.Caps().Features.Has(driver.FeatureTimers) {
|
||||||
t.t = newTimers(g.ctx)
|
t.t = newTimers(g.ctx)
|
||||||
t.compact = t.t.newTimer()
|
t.compact = t.t.newTimer()
|
||||||
t.render = t.t.newTimer()
|
t.render = t.t.newTimer()
|
||||||
@@ -631,13 +629,13 @@ func (g *compute) frame(target RenderTarget) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
t.compact.end()
|
t.compact.end()
|
||||||
if g.collector.profile && t.t.ready() {
|
if false && t.t.ready() {
|
||||||
com, ren, blit := t.compact.Elapsed, t.render.Elapsed, t.blit.Elapsed
|
com, ren, blit := t.compact.Elapsed, t.render.Elapsed, t.blit.Elapsed
|
||||||
ft := com + ren + blit
|
ft := com + ren + blit
|
||||||
q := 100 * time.Microsecond
|
q := 100 * time.Microsecond
|
||||||
ft = ft.Round(q)
|
ft = ft.Round(q)
|
||||||
com, ren, blit = com.Round(q), ren.Round(q), blit.Round(q)
|
com, ren, blit = com.Round(q), ren.Round(q), blit.Round(q)
|
||||||
t.profile = fmt.Sprintf("ft:%7s com: %7s ren:%7s blit:%7s", ft, com, ren, blit)
|
// t.profile = fmt.Sprintf("ft:%7s com: %7s ren:%7s blit:%7s", ft, com, ren, blit)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -661,10 +659,6 @@ func (g *compute) dumpAtlases() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *compute) Profile() string {
|
|
||||||
return g.timers.profile
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *compute) compactAllocs() error {
|
func (g *compute) compactAllocs() error {
|
||||||
const (
|
const (
|
||||||
maxAllocAge = 3
|
maxAllocAge = 3
|
||||||
@@ -1656,7 +1650,6 @@ func (e *encoder) line(start, end f32.Point) {
|
|||||||
|
|
||||||
func (c *collector) reset() {
|
func (c *collector) reset() {
|
||||||
c.prevFrame, c.frame = c.frame, c.prevFrame
|
c.prevFrame, c.frame = c.frame, c.prevFrame
|
||||||
c.profile = false
|
|
||||||
c.clipStates = c.clipStates[:0]
|
c.clipStates = c.clipStates[:0]
|
||||||
c.transStack = c.transStack[:0]
|
c.transStack = c.transStack[:0]
|
||||||
c.frame.reset()
|
c.frame.reset()
|
||||||
@@ -1736,8 +1729,6 @@ func (c *collector) collect(root *op.Ops, viewport image.Point, texOps *[]textur
|
|||||||
c.addClip(&state, fview, fview, nil, ops.Key{}, 0, 0, false)
|
c.addClip(&state, fview, fview, nil, ops.Key{}, 0, 0, false)
|
||||||
for encOp, ok := r.Decode(); ok; encOp, ok = r.Decode() {
|
for encOp, ok := r.Decode(); ok; encOp, ok = r.Decode() {
|
||||||
switch ops.OpType(encOp.Data[0]) {
|
switch ops.OpType(encOp.Data[0]) {
|
||||||
case ops.TypeProfile:
|
|
||||||
c.profile = true
|
|
||||||
case ops.TypeTransform:
|
case ops.TypeTransform:
|
||||||
dop, push := ops.DecodeTransform(encOp.Data)
|
dop, push := ops.DecodeTransform(encOp.Data)
|
||||||
if push {
|
if push {
|
||||||
|
|||||||
+2
-10
@@ -44,10 +44,6 @@ type GPU interface {
|
|||||||
Clear(color color.NRGBA)
|
Clear(color color.NRGBA)
|
||||||
// Frame draws the graphics operations from op into a viewport of target.
|
// Frame draws the graphics operations from op into a viewport of target.
|
||||||
Frame(frame *op.Ops, target RenderTarget, viewport image.Point) error
|
Frame(frame *op.Ops, target RenderTarget, viewport image.Point) error
|
||||||
// Profile returns the last available profiling information. Profiling
|
|
||||||
// information is requested when Frame sees an io/profile.Op, and the result
|
|
||||||
// is available through Profile at some later time.
|
|
||||||
Profile() string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type gpu struct {
|
type gpu struct {
|
||||||
@@ -73,7 +69,6 @@ type renderer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type drawOps struct {
|
type drawOps struct {
|
||||||
profile bool
|
|
||||||
reader ops.Reader
|
reader ops.Reader
|
||||||
states []f32.Affine2D
|
states []f32.Affine2D
|
||||||
transStack []f32.Affine2D
|
transStack []f32.Affine2D
|
||||||
@@ -399,7 +394,7 @@ func (g *gpu) collect(viewport image.Point, frameOps *op.Ops) {
|
|||||||
g.renderer.pather.viewport = viewport
|
g.renderer.pather.viewport = viewport
|
||||||
g.drawOps.reset(viewport)
|
g.drawOps.reset(viewport)
|
||||||
g.drawOps.collect(frameOps, viewport)
|
g.drawOps.collect(frameOps, viewport)
|
||||||
if g.drawOps.profile && g.timers == nil && g.ctx.Caps().Features.Has(driver.FeatureTimers) {
|
if false && g.timers == nil && g.ctx.Caps().Features.Has(driver.FeatureTimers) {
|
||||||
g.frameStart = time.Now()
|
g.frameStart = time.Now()
|
||||||
g.timers = newTimers(g.ctx)
|
g.timers = newTimers(g.ctx)
|
||||||
g.stencilTimer = g.timers.newTimer()
|
g.stencilTimer = g.timers.newTimer()
|
||||||
@@ -444,7 +439,7 @@ func (g *gpu) frame(target RenderTarget) error {
|
|||||||
g.cache.frame()
|
g.cache.frame()
|
||||||
g.drawOps.pathCache.frame()
|
g.drawOps.pathCache.frame()
|
||||||
g.cleanupTimer.end()
|
g.cleanupTimer.end()
|
||||||
if g.drawOps.profile && g.timers.ready() {
|
if false && g.timers.ready() {
|
||||||
st, covt, cleant := g.stencilTimer.Elapsed, g.coverTimer.Elapsed, g.cleanupTimer.Elapsed
|
st, covt, cleant := g.stencilTimer.Elapsed, g.coverTimer.Elapsed, g.cleanupTimer.Elapsed
|
||||||
ft := st + covt + cleant
|
ft := st + covt + cleant
|
||||||
q := 100 * time.Microsecond
|
q := 100 * time.Microsecond
|
||||||
@@ -895,7 +890,6 @@ func (r *renderer) drawLayers(layers []opacityLayer, ops []imageOp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *drawOps) reset(viewport image.Point) {
|
func (d *drawOps) reset(viewport image.Point) {
|
||||||
d.profile = false
|
|
||||||
d.viewport = viewport
|
d.viewport = viewport
|
||||||
d.imageOps = d.imageOps[:0]
|
d.imageOps = d.imageOps[:0]
|
||||||
d.pathOps = d.pathOps[:0]
|
d.pathOps = d.pathOps[:0]
|
||||||
@@ -989,8 +983,6 @@ func (d *drawOps) collectOps(r *ops.Reader, viewport f32.Rectangle) {
|
|||||||
loop:
|
loop:
|
||||||
for encOp, ok := r.Decode(); ok; encOp, ok = r.Decode() {
|
for encOp, ok := r.Decode(); ok; encOp, ok = r.Decode() {
|
||||||
switch ops.OpType(encOp.Data[0]) {
|
switch ops.OpType(encOp.Data[0]) {
|
||||||
case ops.TypeProfile:
|
|
||||||
d.profile = true
|
|
||||||
case ops.TypeTransform:
|
case ops.TypeTransform:
|
||||||
dop, push := ops.DecodeTransform(encOp.Data)
|
dop, push := ops.DecodeTransform(encOp.Data)
|
||||||
if push {
|
if push {
|
||||||
|
|||||||
@@ -76,7 +76,6 @@ const (
|
|||||||
TypeAux
|
TypeAux
|
||||||
TypeClip
|
TypeClip
|
||||||
TypePopClip
|
TypePopClip
|
||||||
TypeProfile
|
|
||||||
TypeCursor
|
TypeCursor
|
||||||
TypePath
|
TypePath
|
||||||
TypeStroke
|
TypeStroke
|
||||||
@@ -162,7 +161,6 @@ const (
|
|||||||
TypeAuxLen = 1
|
TypeAuxLen = 1
|
||||||
TypeClipLen = 1 + 4*4 + 1 + 1
|
TypeClipLen = 1 + 4*4 + 1 + 1
|
||||||
TypePopClipLen = 1
|
TypePopClipLen = 1
|
||||||
TypeProfileLen = 1
|
|
||||||
TypeCursorLen = 2
|
TypeCursorLen = 2
|
||||||
TypePathLen = 8 + 1
|
TypePathLen = 8 + 1
|
||||||
TypeStrokeLen = 1 + 4
|
TypeStrokeLen = 1 + 4
|
||||||
@@ -446,7 +444,6 @@ var opProps = [0x100]opProp{
|
|||||||
TypeAux: {Size: TypeAuxLen, NumRefs: 0},
|
TypeAux: {Size: TypeAuxLen, NumRefs: 0},
|
||||||
TypeClip: {Size: TypeClipLen, NumRefs: 0},
|
TypeClip: {Size: TypeClipLen, NumRefs: 0},
|
||||||
TypePopClip: {Size: TypePopClipLen, NumRefs: 0},
|
TypePopClip: {Size: TypePopClipLen, NumRefs: 0},
|
||||||
TypeProfile: {Size: TypeProfileLen, NumRefs: 1},
|
|
||||||
TypeCursor: {Size: TypeCursorLen, NumRefs: 0},
|
TypeCursor: {Size: TypeCursorLen, NumRefs: 0},
|
||||||
TypePath: {Size: TypePathLen, NumRefs: 0},
|
TypePath: {Size: TypePathLen, NumRefs: 0},
|
||||||
TypeStroke: {Size: TypeStrokeLen, NumRefs: 0},
|
TypeStroke: {Size: TypeStrokeLen, NumRefs: 0},
|
||||||
@@ -531,8 +528,6 @@ func (t OpType) String() string {
|
|||||||
return "Clip"
|
return "Clip"
|
||||||
case TypePopClip:
|
case TypePopClip:
|
||||||
return "PopClip"
|
return "PopClip"
|
||||||
case TypeProfile:
|
|
||||||
return "Profile"
|
|
||||||
case TypeCursor:
|
case TypeCursor:
|
||||||
return "Cursor"
|
return "Cursor"
|
||||||
case TypePath:
|
case TypePath:
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
// SPDX-License-Identifier: Unlicense OR MIT
|
|
||||||
|
|
||||||
// Package profiles provides access to rendering
|
|
||||||
// profiles.
|
|
||||||
package profile
|
|
||||||
|
|
||||||
import (
|
|
||||||
"gioui.org/internal/ops"
|
|
||||||
"gioui.org/io/event"
|
|
||||||
"gioui.org/op"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Op registers a handler for receiving
|
|
||||||
// Events.
|
|
||||||
type Op struct {
|
|
||||||
Tag event.Tag
|
|
||||||
}
|
|
||||||
|
|
||||||
// Event contains profile data from a single
|
|
||||||
// rendered frame.
|
|
||||||
type Event struct {
|
|
||||||
// Timings. Very likely to change.
|
|
||||||
Timings string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p Op) Add(o *op.Ops) {
|
|
||||||
data := ops.Write1(&o.Internal, ops.TypeProfileLen, p.Tag)
|
|
||||||
data[0] = byte(ops.TypeProfile)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p Event) ImplementsEvent() {}
|
|
||||||
@@ -25,7 +25,6 @@ import (
|
|||||||
"gioui.org/io/event"
|
"gioui.org/io/event"
|
||||||
"gioui.org/io/key"
|
"gioui.org/io/key"
|
||||||
"gioui.org/io/pointer"
|
"gioui.org/io/pointer"
|
||||||
"gioui.org/io/profile"
|
|
||||||
"gioui.org/io/semantic"
|
"gioui.org/io/semantic"
|
||||||
"gioui.org/io/system"
|
"gioui.org/io/system"
|
||||||
"gioui.org/io/transfer"
|
"gioui.org/io/transfer"
|
||||||
@@ -54,10 +53,6 @@ type Router struct {
|
|||||||
// InvalidateOp summary.
|
// InvalidateOp summary.
|
||||||
wakeup bool
|
wakeup bool
|
||||||
wakeupTime time.Time
|
wakeupTime time.Time
|
||||||
|
|
||||||
// ProfileOp summary.
|
|
||||||
profHandlers map[event.Tag]struct{}
|
|
||||||
profile profile.Event
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SemanticNode represents a node in the tree describing the components
|
// SemanticNode represents a node in the tree describing the components
|
||||||
@@ -103,10 +98,6 @@ type handlerEvents struct {
|
|||||||
// Events returns the available events for the handler key.
|
// Events returns the available events for the handler key.
|
||||||
func (q *Router) Events(k event.Tag) []event.Event {
|
func (q *Router) Events(k event.Tag) []event.Event {
|
||||||
events := q.handlers.Events(k)
|
events := q.handlers.Events(k)
|
||||||
if _, isprof := q.profHandlers[k]; isprof {
|
|
||||||
delete(q.profHandlers, k)
|
|
||||||
events = append(events, q.profile)
|
|
||||||
}
|
|
||||||
return events
|
return events
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,9 +107,6 @@ func (q *Router) Events(k event.Tag) []event.Event {
|
|||||||
func (q *Router) Frame(frame *op.Ops) {
|
func (q *Router) Frame(frame *op.Ops) {
|
||||||
q.handlers.Clear()
|
q.handlers.Clear()
|
||||||
q.wakeup = false
|
q.wakeup = false
|
||||||
for k := range q.profHandlers {
|
|
||||||
delete(q.profHandlers, k)
|
|
||||||
}
|
|
||||||
var ops *ops.Ops
|
var ops *ops.Ops
|
||||||
if frame != nil {
|
if frame != nil {
|
||||||
ops = &frame.Internal
|
ops = &frame.Internal
|
||||||
@@ -157,8 +145,6 @@ func (q *Router) QueueTopmost(events ...key.Event) bool {
|
|||||||
func (q *Router) Queue(events ...event.Event) bool {
|
func (q *Router) Queue(events ...event.Event) bool {
|
||||||
for _, e := range events {
|
for _, e := range events {
|
||||||
switch e := e.(type) {
|
switch e := e.(type) {
|
||||||
case profile.Event:
|
|
||||||
q.profile = e
|
|
||||||
case pointer.Event:
|
case pointer.Event:
|
||||||
q.pointer.queue.Push(e, &q.handlers)
|
q.pointer.queue.Push(e, &q.handlers)
|
||||||
case key.Event:
|
case key.Event:
|
||||||
@@ -388,12 +374,6 @@ func (q *Router) collect() {
|
|||||||
q.wakeup = true
|
q.wakeup = true
|
||||||
q.wakeupTime = op.At
|
q.wakeupTime = op.At
|
||||||
}
|
}
|
||||||
case ops.TypeProfile:
|
|
||||||
op := decodeProfileOp(encOp.Data, encOp.Refs)
|
|
||||||
if q.profHandlers == nil {
|
|
||||||
q.profHandlers = make(map[event.Tag]struct{})
|
|
||||||
}
|
|
||||||
q.profHandlers[op.Tag] = struct{}{}
|
|
||||||
case ops.TypeClipboardRead:
|
case ops.TypeClipboardRead:
|
||||||
q.cqueue.ProcessReadClipboard(encOp.Refs)
|
q.cqueue.ProcessReadClipboard(encOp.Refs)
|
||||||
case ops.TypeClipboardWrite:
|
case ops.TypeClipboardWrite:
|
||||||
@@ -556,12 +536,6 @@ func (q *Router) collect() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Profiling reports whether there was profile handlers in the
|
|
||||||
// most recent Frame call.
|
|
||||||
func (q *Router) Profiling() bool {
|
|
||||||
return len(q.profHandlers) > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// WakeupTime returns the most recent time for doing another frame,
|
// WakeupTime returns the most recent time for doing another frame,
|
||||||
// as determined from the last call to Frame.
|
// as determined from the last call to Frame.
|
||||||
func (q *Router) WakeupTime() (time.Time, bool) {
|
func (q *Router) WakeupTime() (time.Time, bool) {
|
||||||
@@ -604,15 +578,6 @@ func (h *handlerEvents) Clear() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeProfileOp(d []byte, refs []interface{}) profile.Op {
|
|
||||||
if ops.OpType(d[0]) != ops.TypeProfile {
|
|
||||||
panic("invalid op")
|
|
||||||
}
|
|
||||||
return profile.Op{
|
|
||||||
Tag: refs[0].(event.Tag),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func decodeInvalidateOp(d []byte) op.InvalidateOp {
|
func decodeInvalidateOp(d []byte) op.InvalidateOp {
|
||||||
bo := binary.LittleEndian
|
bo := binary.LittleEndian
|
||||||
if ops.OpType(d[0]) != ops.TypeInvalidate {
|
if ops.OpType(d[0]) != ops.TypeInvalidate {
|
||||||
|
|||||||
Reference in New Issue
Block a user