Sound: nothing that can block in the daemon's start-up; Steam's web compositing in software on open pairs

- The S24 FE (US) daemon hung loading the plain AAudio sink from default.pa (its AAudio open
  blocks rather than fails), so it never finished starting. default.pa is back to DirectAudio
  alone inside .nofail; the fallbacks are loaded from the app once the daemon answers, each pactl
  bounded by its timeout (DirectAudio, then the plain sink with and without low latency). The
  guard waits 30 s and logs, with timestamps, how long the daemon took, whether its socket and
  pactl exist, and what it finally got.
- With an open driver pair on a GPU that is not an Adreno, Steam's CEF composites in software
  (-cef-disable-gpu-compositing) with GPU raster kept: RADV on Xclipse showed stale, half-written
  tiles, as #570 saw on PowerVR. The session log says so.
This commit is contained in:
The412Banner committed 2026-10-12 22:26:00 -04:00
1 parent a8d48e82bc
commit c09e0511c8
3 files changed
+30 -14

No files matched your search

@@ -138,16 +138,6 @@ public class PulseAudioComponent extends SessionPart {
// AAudio sink in its place.
config.add(".nofail");
config.add("load-module module-directaudio-native-sink sink_name=DirectAudio performance_mode=1 adaptive=1 decay=0 limiter=1 watchdog=1 volume=1.0");
if (!com.droiddeck.launcher.core.DeviceSupport.INSTANCE.adreno()) {
// Not an Adreno: the daemon makes its own fallback, without waiting for pactl. A Galaxy
// S24 FE's AAudio refuses DirectAudio's low-latency stream (AAUDIO_ERROR_DISCONNECTED),
// so the plain AAudio sink, without low latency, is loaded as a default underneath it.
// (Loading DirectAudio a second time in the same daemon after its failed first load
// hung the daemon's start-up on that phone, so it is not retried here.) The last
// set-default-sink that names a sink which exists wins.
config.add("load-module module-aaudio-sink sink_name=AAudioSink performance_mode=0 adaptive=1 volume=1.0");
config.add("set-default-sink AAudioSink");
}
config.add("set-default-sink DirectAudio");
config.add(".fail");
if (micFifoPath != null && !micFifoPath.isEmpty()) {
@@ -193,15 +183,24 @@ public class PulseAudioComponent extends SessionPart {
*/
private void ensureClientSink(java.io.PrintWriter out) {
try {
long deadline = System.currentTimeMillis() + 15000L;
// Nothing that may block (a sink whose AAudio open hangs: a Galaxy S24 FE (US) hung the
// daemon's start-up loading one from default.pa) is loaded by the daemon itself; the
// fallbacks are loaded here, after it is up, each pactl call bounded by its timeout.
long started = System.currentTimeMillis();
long deadline = started + 30000L;
String sinks = null;
boolean socketSeen = false;
while (System.currentTimeMillis() < deadline && pid > 1) {
if (socket().exists() && (sinks = pactl("list", "short", "sinks")) != null) break;
socketSeen |= socket().exists();
if (socketSeen && (sinks = pactl("list", "short", "sinks")) != null) break;
try { Thread.sleep(250L); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return; }
}
note(out, "client sink: daemon " + (sinks != null ? "answered" : "did not answer") + " after "
+ (System.currentTimeMillis() - started) + " ms (socket " + (socketSeen ? "present" : "never appeared") + ", pactl "
+ (new File(workingDir, "pactl").isFile() ? "present" : "MISSING") + ", daemon pid " + pid + ")");
String line;
if (sinks == null) {
line = "== client sink: the daemon did not answer in 15 s; no fallback attempted";
line = "== client sink: the daemon did not answer in 30 s; no fallback attempted";
} else if (sinks.contains("\tDirectAudio\t") || sinks.startsWith("DirectAudio\t") || sinks.contains("\tDirectAudio\n") || sinks.matches("(?s).*\\bDirectAudio\\b.*")) {
line = "== client sink: DirectAudio (module-directaudio-native-sink)";
} else {
@@ -215,7 +214,8 @@ public class PulseAudioComponent extends SessionPart {
"adaptive=1", "decay=0", "limiter=1", "watchdog=1", "volume=1.0") != null
&& pactl("set-default-sink", "DirectAudio") != null) {
loadedAs = "DirectAudio on attempt " + attempt;
} else if (pactl("load-module", "module-aaudio-sink", "sink_name=AAudioSink", "performance_mode=1", "adaptive=1", "volume=1.0") != null
} else if (pactl("load-module", "module-aaudio-sink", "sink_name=AAudioSink",
"performance_mode=" + (attempt == 1 ? "1" : "0"), "adaptive=1", "volume=1.0") != null
&& pactl("set-default-sink", "AAudioSink") != null) {
loadedAs = "the plain AAudio sink (AAudioSink) on attempt " + attempt;
}
@@ -231,6 +231,13 @@ public class PulseAudioComponent extends SessionPart {
}
}
/** A timestamped line in the session's audio log. */
private void note(java.io.PrintWriter out, String what) {
String line = "== " + new java.text.SimpleDateFormat("HH:mm:ss.SSS", java.util.Locale.US).format(new java.util.Date()) + " " + what;
Log.i(TAG, line);
if (out != null) synchronized (out) { out.println(line); out.flush(); }
}
/** Runs pactl against this daemon; its stdout, or null when it failed or timed out. */
private String pactl(String... args) {
File pactl = new File(workingDir, "pactl");
@@ -685,6 +685,10 @@ class SessionService : Service() {
}
}
if (!bridge && com.droiddeck.launcher.core.DeviceSupport.openDriverActive(this)) {
// CEF's accelerated shared-texture output showed stale, half-written tiles on RADV
// (Xclipse), as #570 found on PowerVR: web compositing in software, GPU raster kept.
guest.add("BL_STEAM_SOFT_COMPOSITING=1")
Log.i(TAG, "steam: software web compositing for the open driver pair (GPU raster kept)")
LinuxRuntime.gpuStandIn(this)?.takeIf { it == LinuxRuntime.MALI_DEVICE }?.let { guest.add("BL_DRM_STANDIN=$it") }
}
// Turnip's own debug switches, for the runtime's driver and everything on it. The file in
@@ -885,6 +885,11 @@ BUSCONF
# and the selected game driver still use the system GPU.
bl_steam_presentation=(-cef-disable-gpu-compositing)
echo "== steam: system PowerVR uses OpenGL/DRI3 through Zink with software CEF compositing"
elif [ "${BL_STEAM_SOFT_COMPOSITING:-}" = 1 ]; then
# An open driver pair on a GPU that is not an Adreno (RADV on Xclipse, PanVK on Mali): CEF's
# accelerated shared-texture output showed stale tiles there; raster stays on the GPU.
bl_steam_presentation=(-cef-disable-gpu-compositing)
echo "== steam: open driver pair - software CEF compositing, GPU raster"
fi
# The client's CEF flags for this presentation; the UI choice below may replace them.
_bl_cef=(-cef-force-gpu "${bl_steam_presentation[@]}" -cef-use-gl=angle "-cef-use-angle=$bl_steam_angle")