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