mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 07:35:40 +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/key"
|
||||
"gioui.org/io/pointer"
|
||||
"gioui.org/io/profile"
|
||||
"gioui.org/io/router"
|
||||
"gioui.org/io/system"
|
||||
"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)
|
||||
}
|
||||
|
||||
func (w *Window) processFrame(d driver, frameStart time.Time) {
|
||||
func (w *Window) processFrame(d driver) {
|
||||
for k := range w.semantic.ids {
|
||||
delete(w.semantic.ids, k)
|
||||
}
|
||||
@@ -336,13 +335,6 @@ func (w *Window) processFrame(d driver, frameStart time.Time) {
|
||||
w.imeState = 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 {
|
||||
w.setNextFrame(t)
|
||||
}
|
||||
@@ -844,10 +836,6 @@ func (w *Window) processEvent(d driver, e event.Event) bool {
|
||||
break
|
||||
}
|
||||
w.metric = e2.Metric
|
||||
var frameStart time.Time
|
||||
if w.queue.q.Profiling() {
|
||||
frameStart = time.Now()
|
||||
}
|
||||
w.hasNextFrame = false
|
||||
e2.Frame = w.update
|
||||
e2.Queue = &w.queue
|
||||
@@ -891,7 +879,7 @@ func (w *Window) processEvent(d driver, e event.Event) bool {
|
||||
close(w.destroy)
|
||||
break
|
||||
}
|
||||
w.processFrame(d, frameStart)
|
||||
w.processFrame(d)
|
||||
w.updateCursor(d)
|
||||
case system.DestroyEvent:
|
||||
w.destroyGPU()
|
||||
|
||||
+3
-12
@@ -93,7 +93,6 @@ type compute struct {
|
||||
}
|
||||
}
|
||||
timers struct {
|
||||
profile string
|
||||
t *timers
|
||||
compact *timer
|
||||
render *timer
|
||||
@@ -176,7 +175,6 @@ type materialUniforms struct {
|
||||
|
||||
type collector struct {
|
||||
hasher maphash.Hash
|
||||
profile bool
|
||||
reader ops.Reader
|
||||
states []f32.Affine2D
|
||||
clear bool
|
||||
@@ -597,7 +595,7 @@ func (g *compute) frame(target RenderTarget) error {
|
||||
defer g.ctx.EndFrame()
|
||||
|
||||
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.compact = t.t.newTimer()
|
||||
t.render = t.t.newTimer()
|
||||
@@ -631,13 +629,13 @@ func (g *compute) frame(target RenderTarget) error {
|
||||
return err
|
||||
}
|
||||
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
|
||||
ft := com + ren + blit
|
||||
q := 100 * time.Microsecond
|
||||
ft = ft.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
|
||||
}
|
||||
@@ -661,10 +659,6 @@ func (g *compute) dumpAtlases() {
|
||||
}
|
||||
}
|
||||
|
||||
func (g *compute) Profile() string {
|
||||
return g.timers.profile
|
||||
}
|
||||
|
||||
func (g *compute) compactAllocs() error {
|
||||
const (
|
||||
maxAllocAge = 3
|
||||
@@ -1656,7 +1650,6 @@ func (e *encoder) line(start, end f32.Point) {
|
||||
|
||||
func (c *collector) reset() {
|
||||
c.prevFrame, c.frame = c.frame, c.prevFrame
|
||||
c.profile = false
|
||||
c.clipStates = c.clipStates[:0]
|
||||
c.transStack = c.transStack[:0]
|
||||
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)
|
||||
for encOp, ok := r.Decode(); ok; encOp, ok = r.Decode() {
|
||||
switch ops.OpType(encOp.Data[0]) {
|
||||
case ops.TypeProfile:
|
||||
c.profile = true
|
||||
case ops.TypeTransform:
|
||||
dop, push := ops.DecodeTransform(encOp.Data)
|
||||
if push {
|
||||
|
||||
+2
-10
@@ -44,10 +44,6 @@ type GPU interface {
|
||||
Clear(color color.NRGBA)
|
||||
// Frame draws the graphics operations from op into a viewport of target.
|
||||
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 {
|
||||
@@ -73,7 +69,6 @@ type renderer struct {
|
||||
}
|
||||
|
||||
type drawOps struct {
|
||||
profile bool
|
||||
reader ops.Reader
|
||||
states []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.drawOps.reset(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.timers = newTimers(g.ctx)
|
||||
g.stencilTimer = g.timers.newTimer()
|
||||
@@ -444,7 +439,7 @@ func (g *gpu) frame(target RenderTarget) error {
|
||||
g.cache.frame()
|
||||
g.drawOps.pathCache.frame()
|
||||
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
|
||||
ft := st + covt + cleant
|
||||
q := 100 * time.Microsecond
|
||||
@@ -895,7 +890,6 @@ func (r *renderer) drawLayers(layers []opacityLayer, ops []imageOp) {
|
||||
}
|
||||
|
||||
func (d *drawOps) reset(viewport image.Point) {
|
||||
d.profile = false
|
||||
d.viewport = viewport
|
||||
d.imageOps = d.imageOps[:0]
|
||||
d.pathOps = d.pathOps[:0]
|
||||
@@ -989,8 +983,6 @@ func (d *drawOps) collectOps(r *ops.Reader, viewport f32.Rectangle) {
|
||||
loop:
|
||||
for encOp, ok := r.Decode(); ok; encOp, ok = r.Decode() {
|
||||
switch ops.OpType(encOp.Data[0]) {
|
||||
case ops.TypeProfile:
|
||||
d.profile = true
|
||||
case ops.TypeTransform:
|
||||
dop, push := ops.DecodeTransform(encOp.Data)
|
||||
if push {
|
||||
|
||||
@@ -76,7 +76,6 @@ const (
|
||||
TypeAux
|
||||
TypeClip
|
||||
TypePopClip
|
||||
TypeProfile
|
||||
TypeCursor
|
||||
TypePath
|
||||
TypeStroke
|
||||
@@ -162,7 +161,6 @@ const (
|
||||
TypeAuxLen = 1
|
||||
TypeClipLen = 1 + 4*4 + 1 + 1
|
||||
TypePopClipLen = 1
|
||||
TypeProfileLen = 1
|
||||
TypeCursorLen = 2
|
||||
TypePathLen = 8 + 1
|
||||
TypeStrokeLen = 1 + 4
|
||||
@@ -446,7 +444,6 @@ var opProps = [0x100]opProp{
|
||||
TypeAux: {Size: TypeAuxLen, NumRefs: 0},
|
||||
TypeClip: {Size: TypeClipLen, NumRefs: 0},
|
||||
TypePopClip: {Size: TypePopClipLen, NumRefs: 0},
|
||||
TypeProfile: {Size: TypeProfileLen, NumRefs: 1},
|
||||
TypeCursor: {Size: TypeCursorLen, NumRefs: 0},
|
||||
TypePath: {Size: TypePathLen, NumRefs: 0},
|
||||
TypeStroke: {Size: TypeStrokeLen, NumRefs: 0},
|
||||
@@ -531,8 +528,6 @@ func (t OpType) String() string {
|
||||
return "Clip"
|
||||
case TypePopClip:
|
||||
return "PopClip"
|
||||
case TypeProfile:
|
||||
return "Profile"
|
||||
case TypeCursor:
|
||||
return "Cursor"
|
||||
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/key"
|
||||
"gioui.org/io/pointer"
|
||||
"gioui.org/io/profile"
|
||||
"gioui.org/io/semantic"
|
||||
"gioui.org/io/system"
|
||||
"gioui.org/io/transfer"
|
||||
@@ -54,10 +53,6 @@ type Router struct {
|
||||
// InvalidateOp summary.
|
||||
wakeup bool
|
||||
wakeupTime time.Time
|
||||
|
||||
// ProfileOp summary.
|
||||
profHandlers map[event.Tag]struct{}
|
||||
profile profile.Event
|
||||
}
|
||||
|
||||
// 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.
|
||||
func (q *Router) Events(k event.Tag) []event.Event {
|
||||
events := q.handlers.Events(k)
|
||||
if _, isprof := q.profHandlers[k]; isprof {
|
||||
delete(q.profHandlers, k)
|
||||
events = append(events, q.profile)
|
||||
}
|
||||
return events
|
||||
}
|
||||
|
||||
@@ -116,9 +107,6 @@ func (q *Router) Events(k event.Tag) []event.Event {
|
||||
func (q *Router) Frame(frame *op.Ops) {
|
||||
q.handlers.Clear()
|
||||
q.wakeup = false
|
||||
for k := range q.profHandlers {
|
||||
delete(q.profHandlers, k)
|
||||
}
|
||||
var ops *ops.Ops
|
||||
if frame != nil {
|
||||
ops = &frame.Internal
|
||||
@@ -157,8 +145,6 @@ func (q *Router) QueueTopmost(events ...key.Event) bool {
|
||||
func (q *Router) Queue(events ...event.Event) bool {
|
||||
for _, e := range events {
|
||||
switch e := e.(type) {
|
||||
case profile.Event:
|
||||
q.profile = e
|
||||
case pointer.Event:
|
||||
q.pointer.queue.Push(e, &q.handlers)
|
||||
case key.Event:
|
||||
@@ -388,12 +374,6 @@ func (q *Router) collect() {
|
||||
q.wakeup = true
|
||||
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:
|
||||
q.cqueue.ProcessReadClipboard(encOp.Refs)
|
||||
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,
|
||||
// as determined from the last call to Frame.
|
||||
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 {
|
||||
bo := binary.LittleEndian
|
||||
if ops.OpType(d[0]) != ops.TypeInvalidate {
|
||||
|
||||
Reference in New Issue
Block a user