Repository navigation
SurfaceFlinger renderer: RGBA_8888 scan-out slots under the daemon's layout rule #2325
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 |
|---|---|---|
|
|
@@ -217,6 +217,7 @@ import com.winlator.widget.FrameRating | |
| import com.winlator.widget.InputControlsView | ||
| import com.winlator.widget.TouchpadView | ||
| import com.winlator.renderer.ASurfaceRenderer | ||
| import com.winlator.renderer.AHBImage | ||
| import com.winlator.renderer.GLRenderer | ||
| import com.winlator.renderer.VulkanRenderer | ||
| import com.winlator.widget.XServerRendererView | ||
|
|
@@ -262,6 +263,8 @@ import kotlinx.coroutines.withTimeoutOrNull | |
| import org.json.JSONException | ||
| import org.json.JSONObject | ||
| import timber.log.Timber | ||
| import android.system.Os | ||
| import android.system.ErrnoException | ||
| import java.io.File | ||
| import java.io.IOException | ||
| import java.nio.file.Files | ||
|
|
@@ -2128,6 +2131,9 @@ fun XServerScreen( | |
| // other containers as well. Uncheck the per-container useLegacyRenderer | ||
| // setting to switch to the Vulkan renderer. | ||
| val useGLRenderer = isX11Display && (container.graphicsDriver == "virgl" || container.displayRenderer.equals("gl", true)) | ||
| // Before the first drawable: the SurfaceFlinger display renderer hands its window buffers to | ||
| // surfaceflinger, so they follow the same scan-out layout rule as the gamescope daemon's pool. | ||
| if (isX11Display) AHBImage.setCpuScanoutRgba(resolveScanoutLayout(container) == "rgba") | ||
|
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: The X11 path resolves the layout via Prompt for AI agents |
||
| val xServerViewInstance: XServerRendererView = if (useGLRenderer) { | ||
| XServerViewGL(context, xServerToUse) | ||
| } else { | ||
|
|
@@ -6077,6 +6083,29 @@ internal fun resolveDisplayX11(container: Container?): Boolean { | |
| return container == null || Container.isX11Display(container.containerVariant, container.displayServer) | ||
| } | ||
|
|
||
| /** | ||
| * The scan-out layout for buffers this process hands to SurfaceFlinger, "bgra" or "rgba": the container's | ||
| * GNDRM_SCANOUT_LAYOUT override, else the gndrm daemon's device rule (RGBA on Android 16 with a GLES render | ||
| * engine, which aborts surfaceflinger on a BGRA_8888 layer). The override is put in this process's | ||
| * environment first, the way the daemon reads it, and cleared otherwise so an earlier session's does not linger. | ||
| */ | ||
| internal fun resolveScanoutLayout(container: Container): String { | ||
| val override = EnvVars(container.envVars).get("GNDRM_SCANOUT_LAYOUT") | ||
| try { | ||
| if (override.isNotEmpty()) Os.setenv("GNDRM_SCANOUT_LAYOUT", override, true) else Os.unsetenv("GNDRM_SCANOUT_LAYOUT") | ||
| } catch (e: ErrnoException) { | ||
| Timber.w(e, "Could not set GNDRM_SCANOUT_LAYOUT") | ||
| } | ||
| val layout = try { | ||
| GameNativeDrm.nativeScanoutLayout() ?: "bgra" | ||
| } catch (e: LinkageError) { | ||
| Timber.w(e, "Scan-out layout rule unavailable, assuming bgra") | ||
| "bgra" | ||
| } | ||
| Timber.i("X11 scan-out layout %s (%s)", layout, if (override.isNotEmpty()) "container override" else "device rule") | ||
| return layout | ||
| } | ||
|
|
||
| private fun refreshComponentsFiles(context: Context) { | ||
| val extractionPairs = listOf( | ||
| "pulseaudio-gamenative-20260919.tzst" to File(context.filesDir, "pulseaudio"), | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -476,8 +476,11 @@ private void pushCpuImageToNative(int windowId, Drawable drawable) { | |
| long ahbPtr = g.getScanoutHardwareBufferPtr(); | ||
| if (ahbPtr != 0) { | ||
| int acquireFence = g.consumeAcquireFence(); | ||
| // Disable swap R/B in cpu path as it is handled with drawable | ||
| nativeSetWindowBuffer(windowId, ahbPtr, acquireFence, 0, 0, g, g.getLastUsedSlot(), sfCompatMode); | ||
| // Disable swap R/B in cpu path as it is handled with drawable. | ||
| // An RGBA_8888 slot already holds R,G,B,A bytes: SurfaceFlinger takes it as is, and the | ||
| // BGRA-to-RGBA blit (which swaps an RGBA-declared source) must not touch it. | ||
| boolean convert = sfCompatMode && !g.isScanoutRgba(); | ||
|
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. P1: With Prompt for AI agents |
||
| nativeSetWindowBuffer(windowId, ahbPtr, acquireFence, 0, 0, g, g.getLastUsedSlot(), convert); | ||
| if (hudRef != null && skipFPSCount.get() >= 1) { | ||
| hudRef.update(); | ||
| skipFPSCount.set(0); | ||
|
|
||
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: This comment states an unverified universal claim as fact. Describe the layout as the one this renderer uses for CPU scan-out slots, and drop the claim about every render engine.
Prompt for AI agents