github.com/SkycoinProject/gomobile@v0.0.0-20190312151609-d3739f865fa6/exp/app/debug/fps.go (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build darwin linux windows
     6  
     7  // Package debug provides GL-based debugging tools for apps.
     8  package debug // import "golang.org/x/mobile/exp/app/debug"
     9  
    10  import (
    11  	"image"
    12  	"image/color"
    13  	"image/draw"
    14  	"time"
    15  
    16  	"golang.org/x/mobile/event/size"
    17  	"golang.org/x/mobile/exp/gl/glutil"
    18  	"golang.org/x/mobile/geom"
    19  )
    20  
    21  // FPS draws a count of the frames rendered per second.
    22  type FPS struct {
    23  	sz       size.Event
    24  	images   *glutil.Images
    25  	m        *glutil.Image
    26  	lastDraw time.Time
    27  	// TODO: store *gl.Context
    28  }
    29  
    30  // NewFPS creates an FPS tied to the current GL context.
    31  func NewFPS(images *glutil.Images) *FPS {
    32  	return &FPS{
    33  		lastDraw: time.Now(),
    34  		images:   images,
    35  	}
    36  }
    37  
    38  // Draw draws the per second framerate in the bottom-left of the screen.
    39  func (p *FPS) Draw(sz size.Event) {
    40  	const imgW, imgH = 7*(fontWidth+1) + 1, fontHeight + 2
    41  
    42  	if sz.WidthPx == 0 && sz.HeightPx == 0 {
    43  		return
    44  	}
    45  	if p.sz != sz {
    46  		p.sz = sz
    47  		if p.m != nil {
    48  			p.m.Release()
    49  		}
    50  		p.m = p.images.NewImage(imgW, imgH)
    51  	}
    52  
    53  	display := [7]byte{
    54  		4: 'F',
    55  		5: 'P',
    56  		6: 'S',
    57  	}
    58  	now := time.Now()
    59  	f := 0
    60  	if dur := now.Sub(p.lastDraw); dur > 0 {
    61  		f = int(time.Second / dur)
    62  	}
    63  	display[2] = '0' + byte((f/1e0)%10)
    64  	display[1] = '0' + byte((f/1e1)%10)
    65  	display[0] = '0' + byte((f/1e2)%10)
    66  	draw.Draw(p.m.RGBA, p.m.RGBA.Bounds(), image.White, image.Point{}, draw.Src)
    67  	for i, c := range display {
    68  		glyph := glyphs[c]
    69  		if len(glyph) != fontWidth*fontHeight {
    70  			continue
    71  		}
    72  		for y := 0; y < fontHeight; y++ {
    73  			for x := 0; x < fontWidth; x++ {
    74  				if glyph[fontWidth*y+x] == ' ' {
    75  					continue
    76  				}
    77  				p.m.RGBA.SetRGBA((fontWidth+1)*i+x+1, y+1, color.RGBA{A: 0xff})
    78  			}
    79  		}
    80  	}
    81  
    82  	p.m.Upload()
    83  	p.m.Draw(
    84  		sz,
    85  		geom.Point{0, sz.HeightPt - imgH},
    86  		geom.Point{imgW, sz.HeightPt - imgH},
    87  		geom.Point{0, sz.HeightPt},
    88  		p.m.RGBA.Bounds(),
    89  	)
    90  
    91  	p.lastDraw = now
    92  }
    93  
    94  func (f *FPS) Release() {
    95  	if f.m != nil {
    96  		f.m.Release()
    97  		f.m = nil
    98  		f.images = nil
    99  	}
   100  }
   101  
   102  const (
   103  	fontWidth  = 5
   104  	fontHeight = 7
   105  )
   106  
   107  // glyphs comes from the 6x10 fixed font from the plan9port:
   108  // https://github.com/9fans/plan9port/tree/master/font/fixed
   109  //
   110  // 6x10 becomes 5x7 because each glyph has a 1-pixel margin plus space for
   111  // descenders.
   112  //
   113  // Its README file says that those fonts were converted from XFree86, and are
   114  // in the public domain.
   115  var glyphs = [256]string{
   116  	'0': "" +
   117  		"  X  " +
   118  		" X X " +
   119  		"X   X" +
   120  		"X   X" +
   121  		"X   X" +
   122  		" X X " +
   123  		"  X  ",
   124  	'1': "" +
   125  		"  X  " +
   126  		" XX  " +
   127  		"X X  " +
   128  		"  X  " +
   129  		"  X  " +
   130  		"  X  " +
   131  		"XXXXX",
   132  	'2': "" +
   133  		" XXX " +
   134  		"X   X" +
   135  		"    X" +
   136  		"  XX " +
   137  		" X   " +
   138  		"X    " +
   139  		"XXXXX",
   140  	'3': "" +
   141  		"XXXXX" +
   142  		"    X" +
   143  		"   X " +
   144  		"  XX " +
   145  		"    X" +
   146  		"X   X" +
   147  		" XXX ",
   148  	'4': "" +
   149  		"   X " +
   150  		"  XX " +
   151  		" X X " +
   152  		"X  X " +
   153  		"XXXXX" +
   154  		"   X " +
   155  		"   X ",
   156  	'5': "" +
   157  		"XXXXX" +
   158  		"X    " +
   159  		"X XX " +
   160  		"XX  X" +
   161  		"    X" +
   162  		"X   X" +
   163  		" XXX ",
   164  	'6': "" +
   165  		"  XX " +
   166  		" X   " +
   167  		"X    " +
   168  		"X XX " +
   169  		"XX  X" +
   170  		"X   X" +
   171  		" XXX ",
   172  	'7': "" +
   173  		"XXXXX" +
   174  		"    X" +
   175  		"   X " +
   176  		"   X " +
   177  		"  X  " +
   178  		" X   " +
   179  		" X   ",
   180  	'8': "" +
   181  		" XXX " +
   182  		"X   X" +
   183  		"X   X" +
   184  		" XXX " +
   185  		"X   X" +
   186  		"X   X" +
   187  		" XXX ",
   188  	'9': "" +
   189  		" XXX " +
   190  		"X   X" +
   191  		"X  XX" +
   192  		" XX X" +
   193  		"    X" +
   194  		"   X " +
   195  		" XX  ",
   196  	'F': "" +
   197  		"XXXXX" +
   198  		"X    " +
   199  		"X    " +
   200  		"XXXX " +
   201  		"X    " +
   202  		"X    " +
   203  		"X    ",
   204  	'P': "" +
   205  		"XXXX " +
   206  		"X   X" +
   207  		"X   X" +
   208  		"XXXX " +
   209  		"X    " +
   210  		"X    " +
   211  		"X    ",
   212  	'S': "" +
   213  		" XXX " +
   214  		"X   X" +
   215  		"X    " +
   216  		" XXX " +
   217  		"    X" +
   218  		"X   X" +
   219  		" XXX ",
   220  }