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  }