Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 14 additions & 29 deletions app/src/main/runtime/display/XServerDisplayActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ private boolean isAnyControllerConnected() {
private final ArrayList<TaskManagerProcess> taskManagerAccum = new ArrayList<>();
private boolean taskManagerCpuExpanded = false;
private boolean taskManagerPaneVisible = false;
private short[] cachedMaxClockSpeeds;
private CPUStatus.CpuSample prevTaskCpuSample;
private boolean drawerEdgeGesturePossible = false;
private float drawerEdgeGestureStartX = 0f;
private float drawerEdgeGestureStartY = 0f;
Expand Down Expand Up @@ -4965,6 +4965,7 @@ private void stopTaskManagerPolling() {
if (winHandler != null) winHandler.setOnGetProcessInfoListener(null);
taskManagerAccum.clear();
taskManagerCpuExpanded = false;
prevTaskCpuSample = null;
if (drawerStateHolder != null) {
drawerStateHolder.setTaskManagerState(new TaskManagerPaneState(
new ArrayList<>(), 0, 0, new ArrayList<>(), 0, ""));
Expand Down Expand Up @@ -5011,36 +5012,20 @@ private void handleTaskManagerProcessInfo(int index, int numProcesses, ProcessIn
private void pushTaskManagerSystemStats() {
if (drawerStateHolder == null) return;

short[] clockSpeeds = CPUStatus.getCurrentClockSpeeds();
if (cachedMaxClockSpeeds == null || cachedMaxClockSpeeds.length != clockSpeeds.length) {
short[] maxes = new short[clockSpeeds.length];
for (int i = 0; i < clockSpeeds.length; i++) maxes[i] = CPUStatus.getMaxClockSpeed(i);
cachedMaxClockSpeeds = maxes;
}

int totalClock = 0;
short maxClock = 0;
for (int i = 0; i < clockSpeeds.length; i++) {
totalClock += clockSpeeds[i];
if (cachedMaxClockSpeeds[i] > maxClock) maxClock = cachedMaxClockSpeeds[i];
}
CPUStatus.CpuSample cpuSample = CPUStatus.readCpuSample();
int coreCount = cpuSample != null ? cpuSample.coreCount() : 0;
int cpuPercent = 0;
if (clockSpeeds.length > 0 && maxClock > 0) {
int avg = totalClock / clockSpeeds.length;
cpuPercent = (int) (((float) avg / maxClock) * 100.0f);
}

ArrayList<Integer> corePercents;
if (taskManagerCpuExpanded) {
corePercents = new ArrayList<>(clockSpeeds.length);
for (int i = 0; i < clockSpeeds.length; i++) {
short maxFor = cachedMaxClockSpeeds[i];
int corePercent = maxFor > 0 ? (int) (((float) clockSpeeds[i] / maxFor) * 100.0f) : 0;
corePercents.add(corePercent);
ArrayList<Integer> corePercents = new ArrayList<>();
if (cpuSample != null && prevTaskCpuSample != null) {
int agg = cpuSample.percentSince(prevTaskCpuSample);
if (agg >= 0) cpuPercent = agg;
if (taskManagerCpuExpanded) {
for (int i = 0; i < coreCount; i++) {
corePercents.add(cpuSample.corePercentSince(prevTaskCpuSample, i));
}
}
} else {
corePercents = new ArrayList<>();
}
if (cpuSample != null) prevTaskCpuSample = cpuSample;

ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
Expand All @@ -5053,7 +5038,7 @@ private void pushTaskManagerSystemStats() {
drawerStateHolder.setTaskManagerState(new TaskManagerPaneState(
current.getProcesses(),
cpuPercent,
clockSpeeds.length,
coreCount,
corePercents,
memPercent,
memDetail));
Expand Down
51 changes: 39 additions & 12 deletions app/src/main/runtime/display/ui/FrameRating.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ public class FrameRating extends LinearLayout implements Runnable {
private boolean canReadGpu;
private Context context;
private int cpuFailCount;
private CPUStatus.CpuSample prevCpuSample;
private boolean cpuWarmedUp;
private volatile int cpuPercent;
private volatile int cpuTemp;
private volatile int cpuSensorTemp;
Expand Down Expand Up @@ -163,6 +165,7 @@ public void setFrameObserver(FrameObserver observer) {
private static final long FALLBACK_SUPPRESSION_NS = 2000000000L;
private static final long FPS_CALC_INTERVAL_NS = 1000000000L;
private static final long HUD_REFRESH_MS = 1000L;
private static final long CPU_WARMUP_POLL_MS = 500L;
private static final long MIN_FRAME_INTERVAL_NS = 1000000L;
private static final int MAX_FRAME_SAMPLES = 1024;

Expand Down Expand Up @@ -210,6 +213,8 @@ public FrameRating(
this.enableTemp = true;
this.enableRenderer = true;
this.cpuPercent = -1;
this.prevCpuSample = null;
this.cpuWarmedUp = false;
this.gpuLoad = -1;
this.batteryWatts = -1.0f;
this.cpuTemp = -1;
Expand Down Expand Up @@ -299,7 +304,8 @@ public void run() {
if (isStatsRunning) {
calculateStats();
if (statsHandler != null) {
statsHandler.postDelayed(this, 1000L);
long next = (prevCpuSample != null && !cpuWarmedUp) ? CPU_WARMUP_POLL_MS : 1000L;
statsHandler.postDelayed(this, next);
}
}
}
Expand All @@ -311,6 +317,8 @@ private void startStatsUpdate() {
return;
}
this.isStatsRunning = true;
this.prevCpuSample = null;
this.cpuWarmedUp = false;
this.statsThread = new HandlerThread("HardwareStatsThread");
this.statsThread.start();
this.statsHandler = new Handler(this.statsThread.getLooper());
Expand Down Expand Up @@ -1304,7 +1312,8 @@ private int calculateGPULoad() throws Exception {
File[] gpuFiles = {
new File("/sys/class/kgsl/kgsl-3d0/gpu_busy_percentage"),
new File("/sys/class/kgsl/kgsl-3d0/devfreq/gpu_load"),
new File("/sys/class/misc/mali0/device/utilisation")
new File("/sys/class/misc/mali0/device/utilisation"),
new File("/sys/kernel/gpu/gpu_busy")
};

for (File f : gpuFiles) {
Expand All @@ -1319,6 +1328,24 @@ private int calculateGPULoad() throws Exception {
}
}

File mtkMali = new File("/proc/mtk_mali/utilization");
if (mtkMali.exists() && mtkMali.canRead()) {
try (BufferedReader reader = new BufferedReader(new FileReader(mtkMali))) {
String line;
while ((line = reader.readLine()) != null) {
int idx = line.indexOf("ACTIVE=");
if (idx >= 0) {
int start = idx + 7;
int end = line.indexOf(' ', start);
String num = (end > start ? line.substring(start, end) : line.substring(start))
.replaceAll("[^0-9]", "");
if (!num.isEmpty()) return Integer.parseInt(num);
}
}
} catch (Exception ignored) {
}
}

File gpubusy = new File("/sys/class/kgsl/kgsl-3d0/gpubusy");
if (gpubusy.exists() && gpubusy.canRead()) {
try (BufferedReader reader = new BufferedReader(new FileReader(gpubusy))) {
Expand Down Expand Up @@ -1358,18 +1385,18 @@ private void calculateStats() {
}
if (this.enableCpu && this.canReadCpu) {
try {
short[] clocks = CPUStatus.getCurrentClockSpeeds();
if (clocks != null && clocks.length > 0) {
long cur = 0;
long max = 0;
for (int i = 0; i < clocks.length; i++) {
cur += clocks[i];
max += CPUStatus.getMaxClockSpeed(i);
}
if (max > 0) {
this.cpuPercent = (int) ((cur * 100) / max);
CPUStatus.CpuSample sample = CPUStatus.readCpuSample();
if (sample != null) {
if (this.prevCpuSample != null) {
this.cpuPercent = sample.percentSince(this.prevCpuSample);
this.cpuFailCount = 0;
if (!this.cpuWarmedUp) {
this.cpuWarmedUp = true;
Handler refresh = this.uiRefreshHandler;
if (refresh != null) refresh.post(this);
}
}
this.prevCpuSample = sample;
}
} catch (Exception e) {
this.cpuPercent = -1;
Expand Down
96 changes: 96 additions & 0 deletions app/src/main/runtime/system/CPUStatus.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.winlator.cmod.runtime.system;

import com.winlator.cmod.shared.io.FileUtils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Locale;
Expand Down Expand Up @@ -85,4 +87,98 @@ private static int rankCpuZone(String type) {
if (type.contains("big") || type.contains("little")) return 8;
return -1;
}

public static final class CpuSample {
private final long aggBusy;
private final long aggIdle;
private final long[] coreBusy;
private final long[] coreIdle;

private CpuSample(long aggBusy, long aggIdle, long[] coreBusy, long[] coreIdle) {
this.aggBusy = aggBusy;
this.aggIdle = aggIdle;
this.coreBusy = coreBusy;
this.coreIdle = coreIdle;
}

public int coreCount() {
return coreBusy.length;
}

public int percentSince(CpuSample prev) {
if (prev == null) return -1;
return percent(aggBusy - prev.aggBusy, aggIdle - prev.aggIdle);
}

public int corePercentSince(CpuSample prev, int core) {
if (prev == null || core < 0 || core >= coreBusy.length || core >= prev.coreBusy.length)
return 0;
return percent(coreBusy[core] - prev.coreBusy[core], coreIdle[core] - prev.coreIdle[core]);
}

private static int percent(long busyDelta, long idleDelta) {
long total = busyDelta + idleDelta;
if (total <= 0) return 0;
long p = (100 * busyDelta) / total;
if (p < 0) return 0;
if (p > 100) return 100;
return (int) p;
}
}

public static CpuSample readCpuSample() {
int numProcessors = Runtime.getRuntime().availableProcessors();
long[] coreBusy = new long[numProcessors];
long[] coreIdle = new long[numProcessors];
long aggBusy = 0;
long aggIdle = 0;
try (BufferedReader reader = new BufferedReader(new FileReader("/proc/stat"))) {
String line;
while ((line = reader.readLine()) != null) {
if (!line.startsWith("cpu")) break;
String[] f = line.trim().split("\\s+");
if (f.length < 5) continue;
long user = parseTick(f, 1);
long nice = parseTick(f, 2);
long system = parseTick(f, 3);
long idle = parseTick(f, 4);
long iowait = parseTick(f, 5);
long irq = parseTick(f, 6);
long softirq = parseTick(f, 7);
long steal = parseTick(f, 8);
long idleAll = idle + iowait;
long busy = user + nice + system + irq + softirq + steal;
if (f[0].equals("cpu")) {
aggBusy = busy;
aggIdle = idleAll;
} else {
int idx = parseCoreIndex(f[0]);
if (idx >= 0 && idx < numProcessors) {
coreBusy[idx] = busy;
coreIdle[idx] = idleAll;
}
}
}
} catch (Exception e) {
return null;
}
return new CpuSample(aggBusy, aggIdle, coreBusy, coreIdle);
}

private static long parseTick(String[] fields, int index) {
if (index >= fields.length) return 0;
try {
return Long.parseLong(fields[index]);
} catch (NumberFormatException e) {
return 0;
}
}

private static int parseCoreIndex(String label) {
try {
return Integer.parseInt(label.substring(3));
} catch (Exception e) {
return -1;
}
}
}