Selaa lähdekoodia

statistics util panel

leonsal 8 vuotta sitten
vanhempi
commit
a172bfa446
5 muutettua tiedostoa jossa 146 lisäystä ja 12 poistoa
  1. 13 9
      gls/gls.go
  2. 2 0
      gls/program.go
  3. 2 2
      gls/uniform.go
  4. 1 1
      gls/vbo.go
  5. 128 0
      util/stats/stats.go

+ 13 - 9
gls/gls.go

@@ -19,7 +19,7 @@ import (
 // methods to call OpenGL functions.
 type GLS struct {
 	stats               Stats             // statistics
-	Prog                *Program          // current active program
+	prog                *Program          // current active program
 	programs            map[*Program]bool // programs cache
 	checkErrors         bool              // check openGL API errors flag
 	viewportX           int32             // cached last set viewport x
@@ -49,12 +49,15 @@ type GLS struct {
 // Stats contains counters of OpenGL resources being used as well
 // the cummulative numbers of some OpenGL calls for performance evaluation.
 type Stats struct {
-	Vaos      int    // Number of Vertex Array Objects
-	Vbos      int    // Number of Vertex Buffer Objects
-	Textures  int    // Number of Textures
-	Caphits   uint64 // Cummulative number of hits for Enable/Disable
-	Unisets   uint64 // Cummulative number of uniform sets
-	Drawcalls uint64 // Cummulative number of draw calls
+	Shaders    int    // Current number of shader programs
+	Vaos       int    // Number of Vertex Array Objects
+	Vbos       int    // Number of Vertex Buffer Objects
+	Textures   int    // Number of Textures
+	Caphits    uint64 // Cummulative number of hits for Enable/Disable
+	UnilocHits uint64 // Cummulative number of uniform location cache hits
+	UnilocMiss uint64 // Cummulative number of uniform location cache misses
+	Unisets    uint64 // Cummulative number of uniform sets
+	Drawcalls  uint64 // Cummulative number of draw calls
 }
 
 // Polygon side view.
@@ -126,7 +129,7 @@ func (gs *GLS) reset() {
 	gs.depthMask = uintUndef
 	gs.capabilities = make(map[int]int)
 	gs.programs = make(map[*Program]bool)
-	gs.Prog = nil
+	gs.prog = nil
 
 	gs.blendEquation = uintUndef
 	gs.blendSrc = uintUndef
@@ -169,6 +172,7 @@ func (gs *GLS) setDefaultState() {
 func (gs *GLS) Stats(s *Stats) {
 
 	*s = gs.stats
+	s.Shaders = len(gs.programs)
 }
 
 func (gs *GLS) ActiveTexture(texture uint32) {
@@ -627,7 +631,7 @@ func (gs *GLS) UseProgram(prog *Program) {
 		panic("Invalid program")
 	}
 	C.glUseProgram(C.GLuint(prog.handle))
-	gs.Prog = prog
+	gs.prog = prog
 
 	// Inserts program in cache if not already there.
 	if !gs.programs[prog] {

+ 2 - 0
gls/program.go

@@ -159,6 +159,7 @@ func (prog *Program) GetUniformLocation(name string) int32 {
 	// Try to get from the cache
 	loc, ok := prog.uniforms[name]
 	if ok {
+		prog.gs.stats.UnilocHits++
 		return loc
 	}
 	// Get location from GL
@@ -168,6 +169,7 @@ func (prog *Program) GetUniformLocation(name string) int32 {
 	if loc < 0 {
 		log.Warn("GetUniformLocation(%s) NOT FOUND", name)
 	}
+	prog.gs.stats.UnilocMiss++
 	return loc
 }
 

+ 2 - 2
gls/uniform.go

@@ -22,7 +22,7 @@ type Uniform struct {
 // for the current active program
 func (uni *Uniform) Location(gs *GLS) int32 {
 
-	loc := gs.Prog.GetUniformLocation(uni.name)
+	loc := gs.prog.GetUniformLocation(uni.name)
 	return loc
 }
 
@@ -36,7 +36,7 @@ func (uni *Uniform) LocationIdx(gs *GLS, idx int) int32 {
 		uni.idx = idx
 	}
 	//log.Debug("Location(%s, %d)", uni.name, idx)
-	loc := gs.Prog.GetUniformLocation(uni.nameidx)
+	loc := gs.prog.GetUniformLocation(uni.nameidx)
 	return loc
 }
 

+ 1 - 1
gls/vbo.go

@@ -138,7 +138,7 @@ func (vbo *VBO) Transfer(gs *GLS) {
 		elsize := int32(unsafe.Sizeof(float32(0)))
 		for _, attrib := range vbo.attribs {
 			// Get attribute location in the current program
-			loc := gs.Prog.GetAttribLocation(attrib.Name)
+			loc := gs.prog.GetAttribLocation(attrib.Name)
 			if loc < 0 {
 				continue
 			}

+ 128 - 0
util/stats/stats.go

@@ -0,0 +1,128 @@
+package stats
+
+import (
+	"github.com/g3n/engine/gls"
+	"github.com/g3n/engine/gui"
+)
+
+type Stats struct {
+	*gui.Table          // embedded table
+	fields     []*field // array of fields
+}
+
+type field struct {
+	id  string
+	row int
+}
+
+func NewStats(width, height float32) *Stats {
+
+	s := new(Stats)
+	t, err := gui.NewTable(width, height, []gui.TableColumn{
+		{Id: "f", Header: "Stat", Width: 100, Minwidth: 32, Align: gui.AlignRight, Format: "%s", Resize: false, Expand: 0},
+		{Id: "v", Header: "Value", Width: 100, Minwidth: 32, Align: gui.AlignRight, Format: "%d", Resize: false, Expand: 0},
+	})
+	if err != nil {
+		panic(err)
+	}
+	s.Table = t
+	s.addRow("shaders", "Shaders:")
+	s.addRow("vaos", "Vaos:")
+	s.addRow("vbos", "Vbos:")
+	s.addRow("textures", "Textures:")
+	s.addRow("ccalls", "CGO calls/frame:")
+	return s
+}
+
+func (s *Stats) Update(gs *gls.GLS) {
+
+	var stats gls.Stats
+	gs.Stats(&stats)
+	for i := 0; i < len(s.fields); i++ {
+		f := s.fields[i]
+		switch f.id {
+		case "shaders":
+			s.Table.SetCell(f.row, "v", stats.Shaders)
+		case "vaos":
+			s.Table.SetCell(f.row, "v", stats.Vaos)
+		case "vbos":
+			s.Table.SetCell(f.row, "v", stats.Vbos)
+		case "textures":
+			s.Table.SetCell(f.row, "v", stats.Textures)
+		}
+	}
+}
+
+func (s *Stats) addRow(id, label string) {
+
+	f := new(field)
+	f.id = id
+	f.row = s.Table.RowCount()
+	s.Table.AddRow(map[string]interface{}{"f": label, "v": 0})
+	s.fields = append(s.fields, f)
+}
+
+//type field struct {
+//	id     string
+//	label  *gui.Label
+//	value  *gui.Label
+//	align  gui.Align
+//	format string
+//}
+//
+//func NewStats() *Stats {
+//
+//	s := new(Stats)
+//	s.Panel.Initialize(0, 0)
+//	s.addField("shaders", "Shaders", "%d", gui.AlignRight)
+//	s.addField("vaos", "VAOs", "%d", gui.AlignRight)
+//	s.addField("vbos", "VBOs", "%d", gui.AlignRight)
+//	s.addField("textures", "Textures", "%d", gui.AlignRight)
+//	s.recalc()
+//	return s
+//}
+//
+//func (s *Stats) Update(gs *gls.GLS) {
+//
+//	var stats gls.Stats
+//	gs.Stats(&stats)
+//	for i := 0; i < len(s.fields); i++ {
+//		f := s.fields[i]
+//		switch f.id {
+//		case "shaders":
+//			f.value.SetText(fmt.Sprintf(f.format, stats.Shaders))
+//		case "vaos":
+//			f.value.SetText(fmt.Sprintf(f.format, stats.Vaos))
+//		case "vbos":
+//			f.value.SetText(fmt.Sprintf(f.format, stats.Vbos))
+//		case "textures":
+//			f.value.SetText(fmt.Sprintf(f.format, stats.Textures))
+//		}
+//	}
+//}
+//
+//func (s *Stats) addField(id, label string, format string, align gui.Align) {
+//
+//	f := new(field)
+//	f.id = id
+//	f.label = gui.NewLabel(label)
+//	f.value = gui.NewLabel("")
+//	f.align = align
+//}
+//
+//func (s *Stats) recalc() {
+//
+//	maxLabelWidth := 0
+//	for i := 0; i < len(s.fields); i ++ {
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//	}
+//}