gioui.org/ui@v0.0.0-20190926171558-ce74bc0cbaea/app/internal/gpu/timer.go (about) 1 // SPDX-License-Identifier: Unlicense OR MIT 2 3 package gpu 4 5 import ( 6 "time" 7 8 "gioui.org/ui/app/internal/gl" 9 ) 10 11 type timers struct { 12 ctx *context 13 timers []*timer 14 } 15 16 type timer struct { 17 Elapsed time.Duration 18 ctx *context 19 obj gl.Query 20 state timerState 21 } 22 23 type timerState uint8 24 25 const ( 26 timerIdle timerState = iota 27 timerRunning 28 timerWaiting 29 ) 30 31 func newTimers(ctx *context) *timers { 32 return &timers{ 33 ctx: ctx, 34 } 35 } 36 37 func (t *timers) newTimer() *timer { 38 if t == nil { 39 return nil 40 } 41 tt := &timer{ 42 ctx: t.ctx, 43 obj: t.ctx.CreateQuery(), 44 } 45 t.timers = append(t.timers, tt) 46 return tt 47 } 48 49 func (t *timer) begin() { 50 if t == nil || t.state != timerIdle { 51 return 52 } 53 t.ctx.BeginQuery(gl.TIME_ELAPSED_EXT, t.obj) 54 t.state = timerRunning 55 } 56 57 func (t *timer) end() { 58 if t == nil || t.state != timerRunning { 59 return 60 } 61 t.ctx.EndQuery(gl.TIME_ELAPSED_EXT) 62 t.state = timerWaiting 63 } 64 65 func (t *timers) ready() bool { 66 if t == nil { 67 return false 68 } 69 for _, tt := range t.timers { 70 if tt.state != timerWaiting { 71 return false 72 } 73 if t.ctx.GetQueryObjectuiv(tt.obj, gl.QUERY_RESULT_AVAILABLE) == 0 { 74 return false 75 } 76 } 77 for _, tt := range t.timers { 78 tt.state = timerIdle 79 nanos := t.ctx.GetQueryObjectuiv(tt.obj, gl.QUERY_RESULT) 80 tt.Elapsed = time.Duration(nanos) 81 } 82 return t.ctx.GetInteger(gl.GPU_DISJOINT_EXT) == 0 83 } 84 85 func (t *timers) release() { 86 if t == nil { 87 return 88 } 89 for _, tt := range t.timers { 90 t.ctx.DeleteQuery(tt.obj) 91 } 92 t.timers = nil 93 }