Repository navigation
HUD and telemetry: report the game's fps and the displayed fps on both display servers #2334
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -844,6 +844,8 @@ fun XServerScreen( | |
|
|
||
| fun refreshFpsLimit(view: View?, isX11Display: Boolean) { | ||
| val refreshHz = detectRefreshRateHz(context, view) | ||
| // The ceiling of the displayed-fps estimate, on both display servers. | ||
| FrameRating.setPanelRefreshHz(refreshHz.toFloat()) | ||
|
Comment on lines
+847
to
+848
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| ui.detectedMaxRefreshRateHz = refreshHz * FPS_LIMITER_MAX_MULTIPLIER | ||
|
|
||
| if (!isX11Display) | ||
|
|
@@ -5435,7 +5437,12 @@ private fun exit( | |
| "game_name" to ContainerUtils.resolveGameName(appId), | ||
| "game_store" to ContainerUtils.extractGameSourceFromContainerId(appId).name, | ||
| "session_length" to (frameRating?.sessionLengthSec ?: 0), | ||
| // avg_fps is the game's fps (frames it produced; see FrameRating). game_fps repeats it | ||
| // under an explicit name, and displayed_fps is the same readings clamped to the panel's | ||
| // rate, an estimate of the frames that reached the panel. | ||
| "avg_fps" to (frameRating?.avgFPS ?: 0.0), | ||
| "game_fps" to (frameRating?.avgFPS ?: 0.0), | ||
| "displayed_fps" to (frameRating?.avgDisplayedFPS ?: 0.0), | ||
| "container_config" to container.containerJson, | ||
| ) + runCatching { | ||
| PluviaApp.xServerView?.getxServer()?.effectiveScreenInfo | ||
|
|
@@ -5456,6 +5463,7 @@ private fun exit( | |
| // Store session data in container metadata | ||
| frameRating?.let { rating -> | ||
| container.putSessionMetadata("avg_fps", rating.avgFPS) | ||
| container.putSessionMetadata("displayed_fps", rating.avgDisplayedFPS) | ||
| container.putSessionMetadata("session_length_sec", rating.sessionLengthSec.toInt()) | ||
| container.putSessionMetadata("total_frames", rating.totalFrames) | ||
| container.saveData() | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -9,6 +9,25 @@ import kotlin.math.roundToInt | |||||||||||||||||||||||
| internal object PerformanceHudText { | ||||||||||||||||||||||||
| private const val MISSING = "--" | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||
| * FPS row: the frames that reached the panel, then in brackets the frames the game produced | ||||||||||||||||||||||||
| * when the two differ. "FPS 60 (287)" is a game rendering 287 frames a second on a 60 Hz | ||||||||||||||||||||||||
| * panel; "FPS 59.8" is a game at or below the panel's rate, where the two are the same. | ||||||||||||||||||||||||
| * | ||||||||||||||||||||||||
| * [gameFps] is what the session counts on either display server (see FrameRating). The | ||||||||||||||||||||||||
| * displayed figure is an estimate: [gameFps] clamped to [refreshHz]; no renderer reports the | ||||||||||||||||||||||||
| * frames the panel actually latched. With no refresh rate known the row is the game's fps. | ||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||
| fun fps(gameFps: Float, refreshHz: Float): String { | ||||||||||||||||||||||||
| val game = if (gameFps.isFinite()) gameFps.coerceAtLeast(0f) else 0f | ||||||||||||||||||||||||
| val hz = refreshHz.takeIf { it.isFinite() && it > 0f } | ||||||||||||||||||||||||
| return if (hz != null && game > hz + 0.5f) { | ||||||||||||||||||||||||
| String.format(Locale.US, "FPS %d (%d)", hz.roundToInt(), game.roundToInt()) | ||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||
| String.format(Locale.US, "FPS %.1f", game) | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
Comment on lines
+24
to
+28
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: At Prompt for AI agents
Suggested change
|
||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||
| * GPU row. The percent is always the active usage source's reading (sysfs, Mali counters | ||||||||||||||||||||||||
| * or the shim); a measured GPU frame time is appended, never substituted: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -347,7 +347,7 @@ class PerformanceHudView( | |
| fpsValue = currentFps, | ||
| cpuValue = cpuPercent?.toFloat(), | ||
| gpuValue = gpuPercent?.toFloat(), | ||
| fps = String.format(Locale.US, "FPS %.1f", currentFps), | ||
| fps = PerformanceHudText.fps(currentFps, refreshHz), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: After a display-mode change, this still formats against the collector’s startup-only refresh rate, so the HUD can show the old panel rate. Use the live panel rate or update the collector when Prompt for AI agents
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| cpu = cpuPercent?.let { "CPU $it%" }, | ||
| gpu = PerformanceHudText.gpu(gpuPercent, gpuFrameMs), | ||
| gpuCompact = PerformanceHudText.gpu(gpuPercent, gpuFrameMs, compact = true), | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P3: The new
displayed=log value clamps toFrameRating's rounded panel rate, but the HUD clamps toPerformanceMetricsCollector.refreshRateHz(the raw DisplayManager rate). On fractional or external-display setups the two can differ. Derive the log's displayed value from the samedisplayRefreshRatethe HUD uses, or make both read one source.Prompt for AI agents