From 3648bdc02a761f9c3f30bbcc531695d1035bac09 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Sat, 7 Oct 2023 19:12:18 -0500 Subject: [PATCH] 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 --- app/window.go | 16 ++-------------- gpu/compute.go | 15 +++------------ gpu/gpu.go | 12 ++---------- internal/ops/ops.go | 5 ----- io/profile/profile.go | 31 ------------------------------- io/router/router.go | 35 ----------------------------------- 6 files changed, 7 insertions(+), 107 deletions(-) delete mode 100644 io/profile/profile.go diff --git a/app/window.go b/app/window.go index a38e7406..3b1ee9af 100644 --- a/app/window.go +++ b/app/window.go @@ -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() diff --git a/gpu/compute.go b/gpu/compute.go index 65cea7c7..298a5b87 100644 --- a/gpu/compute.go +++ b/gpu/compute.go @@ -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 { diff --git a/gpu/gpu.go b/gpu/gpu.go index 362eb141..e481af7f 100644 --- a/gpu/gpu.go +++ b/gpu/gpu.go @@ -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 { diff --git a/internal/ops/ops.go b/internal/ops/ops.go index adac510f..fbc2f44c 100644 --- a/internal/ops/ops.go +++ b/internal/ops/ops.go @@ -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: diff --git a/io/profile/profile.go b/io/profile/profile.go deleted file mode 100644 index b9a4476e..00000000 --- a/io/profile/profile.go +++ /dev/null @@ -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() {} diff --git a/io/router/router.go b/io/router/router.go index 92c2b10a..4bc2a9a4 100644 --- a/io/router/router.go +++ b/io/router/router.go @@ -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 {