summaryrefslogtreecommitdiff
path: root/internal/display/cpu.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/display/cpu.go')
-rw-r--r--internal/display/cpu.go151
1 files changed, 151 insertions, 0 deletions
diff --git a/internal/display/cpu.go b/internal/display/cpu.go
new file mode 100644
index 0000000..1b9edaf
--- /dev/null
+++ b/internal/display/cpu.go
@@ -0,0 +1,151 @@
+package display
+
+import (
+ "sort"
+
+ "codeberg.org/snonux/loadbars/internal/constants"
+ "codeberg.org/snonux/loadbars/internal/stats"
+ "github.com/veandco/go-sdl2/sdl"
+)
+
+func peakPctForBar(state *runState, key string, cpuAvg int, s *[10]float64) float64 {
+ if !state.extended || s == nil {
+ return 0
+ }
+ userSys := (*s)[0] + (*s)[1]
+ hist := state.peakHistory[key]
+ hist = append(hist, userSys)
+ n := cpuAvg
+ if n < 1 {
+ n = 1
+ }
+ for len(hist) > n {
+ hist = hist[1:]
+ }
+ state.peakHistory[key] = hist
+ var max float64
+ for _, v := range hist {
+ if v > max {
+ max = v
+ }
+ }
+ return max
+}
+
+func sortedCPUNames(cpu map[string]stats.CPULine, cpuMode int) []string {
+ if cpuMode == constants.CPUModeOff {
+ return nil
+ }
+ var names []string
+ for name := range cpu {
+ if name == "cpu" {
+ names = append(names, "cpu")
+ continue
+ }
+ if cpuMode == constants.CPUModeCores {
+ names = append(names, name)
+ }
+ }
+ sort.Slice(names, func(i, j int) bool {
+ if names[i] == "cpu" {
+ return true
+ }
+ if names[j] == "cpu" {
+ return false
+ }
+ return names[i] < names[j]
+ })
+ return names
+}
+
+// cpuBarTargetPcts returns the 9 segment percentages (system, user, nice, idle, iowait, irq, softirq, guest, steal) from cur/prev delta.
+func cpuBarTargetPcts(cur, prev stats.CPULine) (out [10]float64, ok bool) {
+ totalCur := cur.Total()
+ totalPrev := prev.Total()
+ if totalPrev == 0 || totalCur <= totalPrev {
+ return out, false
+ }
+ scale := float64(totalCur-totalPrev) / 100.0
+ if scale <= 0 {
+ return out, false
+ }
+ out[0] = float64(cur.System-prev.System) / scale
+ out[1] = float64(cur.User-prev.User) / scale
+ out[2] = float64(cur.Nice-prev.Nice) / scale
+ out[3] = float64(cur.Idle-prev.Idle) / scale
+ out[4] = float64(cur.Iowait-prev.Iowait) / scale
+ out[5] = float64(cur.IRQ-prev.IRQ) / scale
+ out[6] = float64(cur.SoftIRQ-prev.SoftIRQ) / scale
+ out[7] = float64(cur.Guest-prev.Guest) / scale
+ out[8] = float64(cur.Steal-prev.Steal) / scale
+ out[9] = float64(cur.GuestNice-prev.GuestNice) / scale
+ for i := range out {
+ if out[i] < 0 {
+ out[i] = 0
+ }
+ if out[i] > 100 {
+ out[i] = 100
+ }
+ }
+ return out, true
+}
+
+func normalizePcts(s *[10]float64) {
+ var sum float64
+ for i := 0; i < 10; i++ {
+ sum += (*s)[i]
+ }
+ if sum <= 0 {
+ return
+ }
+ for i := 0; i < 10; i++ {
+ (*s)[i] = (*s)[i] * 100 / sum
+ }
+}
+
+func drawCPUBarFromPcts(renderer *sdl.Renderer, s *[10]float64, barW int32, x, y, barH int32, extended bool, peakPct float64) {
+ renderer.SetDrawColor(constants.Black.R, constants.Black.G, constants.Black.B, 255)
+ renderer.FillRect(&sdl.Rect{X: x, Y: y, W: barW, H: barH})
+ if s == nil {
+ return
+ }
+ pxPerPct := float64(barH) / 100.0
+ curY := float64(y + barH)
+ fill := func(r, g, b uint8, pct float64) {
+ hh := int32(pct * pxPerPct)
+ if hh < 1 && pct > 0 {
+ hh = 1
+ }
+ curY -= float64(hh)
+ renderer.SetDrawColor(r, g, b, 255)
+ renderer.FillRect(&sdl.Rect{X: x, Y: int32(curY), W: barW, H: hh})
+ }
+ fill(constants.Blue.R, constants.Blue.G, constants.Blue.B, (*s)[0])
+ fill(constants.Yellow.R, constants.Yellow.G, constants.Yellow.B, (*s)[1])
+ fill(constants.Green.R, constants.Green.G, constants.Green.B, (*s)[2])
+ fill(constants.LimeGreen.R, constants.LimeGreen.G, constants.LimeGreen.B, (*s)[9])
+ fill(constants.Black.R, constants.Black.G, constants.Black.B, (*s)[3])
+ fill(constants.Purple.R, constants.Purple.G, constants.Purple.B, (*s)[4])
+ fill(constants.White.R, constants.White.G, constants.White.B, (*s)[5])
+ fill(constants.White.R, constants.White.G, constants.White.B, (*s)[6])
+ fill(constants.Red.R, constants.Red.G, constants.Red.B, (*s)[7])
+ fill(constants.Red.R, constants.Red.G, constants.Red.B, (*s)[8])
+ if !extended || peakPct <= 0 {
+ return
+ }
+ peakY := y + barH - int32(peakPct*pxPerPct)
+ if peakY < y {
+ peakY = y
+ }
+ if peakY >= y+barH {
+ peakY = y + barH - 1
+ }
+ if peakPct > float64(constants.UserOrangeThreshold) {
+ renderer.SetDrawColor(constants.Orange.R, constants.Orange.G, constants.Orange.B, 255)
+ } else if peakPct > float64(constants.UserYellowThreshold) {
+ renderer.SetDrawColor(constants.Yellow0.R, constants.Yellow0.G, constants.Yellow0.B, 255)
+ } else {
+ renderer.SetDrawColor(constants.Yellow.R, constants.Yellow.G, constants.Yellow.B, 255)
+ }
+ renderer.FillRect(&sdl.Rect{X: x, Y: peakY, W: barW, H: 1})
+}