Skip to content

perf(android): ADPF power-efficiency bias, GC no-region, nursery 8m, OEM game modes, minimal post-processing - #310

Merged
winnerspiros merged 7 commits into
masterfrom
copilot/optimize-osu-performance
May 8, 2026
Merged

perf(android): ADPF power-efficiency bias, GC no-region, nursery 8m, OEM game modes, minimal post-processing#310
winnerspiros merged 7 commits into
masterfrom
copilot/optimize-osu-performance

Conversation

Copilot AI commented May 8, 2026

Copy link
Copy Markdown
  • Fix ambiguous cref="GC.TryStartNoGCRegion" XML doc warnings → cref="GC.TryStartNoGCRegion(long, bool)"

Copilot AI and others added 6 commits May 8, 2026 07:54
Agent-Logs-Url: https://github.com/winnerspiros/osu/sessions/308e53dd-8e58-4c88-bce2-a507f3bc571e

Co-authored-by: winnerspiros <1675249+winnerspiros@users.noreply.github.com>
…tings

Agent-Logs-Url: https://github.com/winnerspiros/osu/sessions/308e53dd-8e58-4c88-bce2-a507f3bc571e

Co-authored-by: winnerspiros <1675249+winnerspiros@users.noreply.github.com>
…EM game modes, VP9 deadline=best

Agent-Logs-Url: https://github.com/winnerspiros/osu/sessions/2523e170-1d43-41d8-af53-47db9142dcaa

Co-authored-by: winnerspiros <1675249+winnerspiros@users.noreply.github.com>
Agent-Logs-Url: https://github.com/winnerspiros/osu/sessions/2523e170-1d43-41d8-af53-47db9142dcaa

Co-authored-by: winnerspiros <1675249+winnerspiros@users.noreply.github.com>
…atency

Agent-Logs-Url: https://github.com/winnerspiros/osu/sessions/2523e170-1d43-41d8-af53-47db9142dcaa

Co-authored-by: winnerspiros <1675249+winnerspiros@users.noreply.github.com>
…comments

Agent-Logs-Url: https://github.com/winnerspiros/osu/sessions/2523e170-1d43-41d8-af53-47db9142dcaa

Co-authored-by: winnerspiros <1675249+winnerspiros@users.noreply.github.com>
@gitar-bot

gitar-bot Bot commented May 8, 2026

Copy link
Copy Markdown

Gitar is working

Gitar

Copilot AI requested a review from winnerspiros May 8, 2026 08:59
@winnerspiros
winnerspiros marked this pull request as ready for review May 8, 2026 10:07
Copilot AI review requested due to automatic review settings May 8, 2026 10:07
@winnerspiros
winnerspiros merged commit 1263d53 into master May 8, 2026
22 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR focuses on Android performance/latency tuning and updates the CI resource-override optimizer to choose more space-efficient media formats (including optional JPEG→AVIF), alongside updated optimizer defaults.

Changes:

  • Add Android performance hints/toggles: ADPF “prefer performance” bias, attempt to use GC.TryStartNoGCRegion(), compositor minimal post-processing, and Mono GC nursery sizing.
  • Extend optimize_resource_overrides.py to pick the smallest acceptable image output among WebP (lossless/lossy) and optional JPEG→AVIF, plus improved Opus mono bitrate handling.
  • Register additional OEM “game mode” metadata keys in the Android manifest.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
scripts/optimize_resource_overrides.py Adds multi-candidate image conversion (WebP + optional AVIF) and mono/stereo Opus bitrate selection.
osu.Android/Performance/AndroidHighPerformanceSessionManager.cs Attempts to start/end a no-GC region during high-performance sessions with one-shot runtime support detection.
osu.Android/OsuGameAndroid.cs Disables ADPF power-efficiency bias for Draw/Update/Input hint sessions (API 35+ via native no-op fallback).
osu.Android/OsuGameActivity.cs Requests minimal post-processing on the window to reduce display pipeline latency.
osu.Android/Native/OboeAudioBridge.cs Adds P/Invoke for nADPFSetPreferPowerEfficiency.
osu.Android/Native/oboe_bridge.cpp Implements nADPFSetPreferPowerEfficiency via dlsym to avoid linker issues on pre-API-35 devices.
osu.Android/mono.env Increases Mono Gen0 nursery size to 8 MB via MONO_GC_PARAMS.
osu.Android/AndroidManifest.xml Adds OEM-specific <meta-data> flags to trigger vendor game modes.
.github/resource-optimizer/osu-resources-config.json Updates optimizer thresholds/qualities and enables JPEG→AVIF + mono Opus bitrate.
.github/resource-optimizer/config.json Updates default optimizer thresholds/qualities and enables JPEG→AVIF + mono Opus bitrate.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +115 to +133
p = source.parent / f".{source.stem}.lossless.webp.tmp"
run_ffmpeg(
[
"-i",
str(source),
"-c:v",
"libwebp",
"-lossless",
"1",
"-compression_level",
str(config.get("png_webp_lossless_compression_level", 6)),
"-f",
"webp",
str(lossless_path),
"-i", str(source),
"-c:v", "libwebp",
"-lossless", "1",
"-compression_level", str(config.get("png_webp_lossless_compression_level", 9)),
"-f", "webp", str(p),
]
)
temp_candidates.append((lossless_path, "png-lossless-webp"))
temp_candidates.append((p, "png-lossless-webp", True, ".webp"))

# ── WebP lossy ───────────────────────────────────────────────────────────
has_alpha = ext == ".png" and ffprobe_has_alpha_channel(source)
lossy_quality = (
config.get("png_webp_alpha_lossy_quality", 95) if has_alpha else config.get("png_webp_lossy_quality", 92)
config.get("png_webp_alpha_lossy_quality", 95) if has_alpha else config.get("png_webp_lossy_quality", 90)
) if ext == ".png" else config.get("jpeg_webp_quality", 88)
lossy_method = config.get("png_webp_lossy_method", 6) if ext == ".png" else config.get("jpeg_webp_method", 6)
lossy_path = source.parent / f".{output.name}.lossy.tmp"
p_webp = source.parent / f".{source.stem}.lossy.webp.tmp"
Comment on lines +113 to +143
# ── WebP lossless (PNG only) ─────────────────────────────────────────────
if ext == ".png" and bool(config.get("png_webp_try_lossless", True)):
lossless_path = source.parent / f".{output.name}.lossless.tmp"
p = source.parent / f".{source.stem}.lossless.webp.tmp"
run_ffmpeg(
[
"-i",
str(source),
"-c:v",
"libwebp",
"-lossless",
"1",
"-compression_level",
str(config.get("png_webp_lossless_compression_level", 6)),
"-f",
"webp",
str(lossless_path),
"-i", str(source),
"-c:v", "libwebp",
"-lossless", "1",
"-compression_level", str(config.get("png_webp_lossless_compression_level", 9)),
"-f", "webp", str(p),
]
)
temp_candidates.append((lossless_path, "png-lossless-webp"))
temp_candidates.append((p, "png-lossless-webp", True, ".webp"))

# ── WebP lossy ───────────────────────────────────────────────────────────
has_alpha = ext == ".png" and ffprobe_has_alpha_channel(source)
lossy_quality = (
config.get("png_webp_alpha_lossy_quality", 95) if has_alpha else config.get("png_webp_lossy_quality", 92)
config.get("png_webp_alpha_lossy_quality", 95) if has_alpha else config.get("png_webp_lossy_quality", 90)
) if ext == ".png" else config.get("jpeg_webp_quality", 88)
lossy_method = config.get("png_webp_lossy_method", 6) if ext == ".png" else config.get("jpeg_webp_method", 6)
lossy_path = source.parent / f".{output.name}.lossy.tmp"
p_webp = source.parent / f".{source.stem}.lossy.webp.tmp"
run_ffmpeg(
[
"-i",
str(source),
"-c:v",
"libwebp",
"-q:v",
str(lossy_quality),
"-compression_level",
str(lossy_method),
"-f",
"webp",
str(lossy_path),
"-i", str(source),
"-c:v", "libwebp",
"-q:v", str(lossy_quality),
"-compression_level", str(lossy_method),
"-f", "webp", str(p_webp),
]
)
lossy_strategy = f"{ext.lstrip('.')}-lossy-webp-q{lossy_quality}"
temp_candidates.append((lossy_path, lossy_strategy))

minimum_ssim = float(config.get("image_lossy_min_ssim", 0.995))
temp_candidates.append((p_webp, f"{ext.lstrip('.')}-lossy-webp-q{lossy_quality}", False, ".webp"))
Comment on lines +851 to +859
typedef void (*SetPreferPowerEfficiencyFn)(APerformanceHintSession*, bool);
static SetPreferPowerEfficiencyFn fn = nullptr;
static bool resolved = false;

if (!resolved) {
fn = reinterpret_cast<SetPreferPowerEfficiencyFn>(
dlsym(RTLD_DEFAULT, "APerformanceHintSession_setPreferPowerEfficiency"));
resolved = true;
}
Comment on lines +131 to +135
catch
{
noGCRegionSupported = false;
Logger.Log("GC.TryStartNoGCRegion unsupported on this runtime; skipping no-GC region.");
}
Comment on lines +168 to +174
catch
{
// EndNoGCRegion can throw InvalidOperationException if we are not actually
// inside a no-GC region (e.g. budget was exhausted and the runtime exited
// it automatically). Swallow: the goal was to reduce pauses and the
// runtime has already managed the transition gracefully.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants