From e93ee35ea273a47fa45ee9eed4370c54f4828bf6 Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Thu, 29 Oct 2026 15:09:55 +0100 Subject: [PATCH] Read back screenshots in their own format --- src/Sentry.Unity/SentryScreenshot.cs | 9 +++++---- .../SentryScreenshotTests.cs | 20 +++++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/Sentry.Unity/SentryScreenshot.cs b/src/Sentry.Unity/SentryScreenshot.cs index c3ff3bf46..e2ea0e677 100644 --- a/src/Sentry.Unity/SentryScreenshot.cs +++ b/src/Sentry.Unity/SentryScreenshot.cs @@ -2,7 +2,6 @@ using System.Threading.Tasks; using Sentry.Extensibility; using UnityEngine; -using UnityEngine.Experimental.Rendering; using UnityEngine.Rendering; namespace Sentry.Unity; @@ -56,11 +55,13 @@ internal static void CaptureAsync(SentryUnityOptions options, Action on { var renderTexture = CaptureIntoRenderTexture(options, Screen.width, Screen.height); var (width, height) = ((uint)renderTexture.width, (uint)renderTexture.height); + var format = renderTexture.graphicsFormat; try { - // The texture has to stay out of the pool until the readback is done with it - AsyncGPUReadback.Request(renderTexture, 0, TextureFormat.RGBA32, readback => + // The texture has to stay out of the pool until the readback is done with it. Reading it back in its own + // format, as converting fails for formats the platform can't ReadPixels from, e.g. BGRA on Metal. + AsyncGPUReadback.Request(renderTexture, 0, readback => { RenderTexture.ReleaseTemporary(renderTexture); @@ -77,7 +78,7 @@ internal static void CaptureAsync(SentryUnityOptions options, Action on byte[]? bytes = null; try { - bytes = ImageConversion.EncodeArrayToJPG(pixels, GraphicsFormat.R8G8B8A8_UNorm, width, height, + bytes = ImageConversion.EncodeArrayToJPG(pixels, format, width, height, 0, options.ScreenshotCompression); } catch (Exception e) diff --git a/test/Sentry.Unity.Tests/SentryScreenshotTests.cs b/test/Sentry.Unity.Tests/SentryScreenshotTests.cs index f3724687e..f532b2172 100644 --- a/test/Sentry.Unity.Tests/SentryScreenshotTests.cs +++ b/test/Sentry.Unity.Tests/SentryScreenshotTests.cs @@ -1,5 +1,8 @@ +using System.Collections; +using System.Threading.Tasks; using NUnit.Framework; using UnityEngine; +using UnityEngine.TestTools; namespace Sentry.Unity.Tests; @@ -61,4 +64,21 @@ public void CaptureScreenshot_RestoresActiveRenderTexture() Object.Destroy(gameTarget); } } + + // Unity logs an error when the readback has to convert from a format it can't ReadPixels from, e.g. BGRA on Metal + [UnityTest] + public IEnumerator CaptureAsync_ReadsBackScreenshot() + { + if (!SystemInfo.supportsAsyncGPUReadback) + { + Assert.Ignore("Async GPU readback is not supported."); + } + + var screenshot = new TaskCompletionSource(); + + SentryScreenshot.CaptureAsync(new SentryUnityOptions(), bytes => screenshot.SetResult(bytes)); + yield return new WaitUntil(() => screenshot.Task.IsCompleted); + + Assert.IsNotEmpty(screenshot.Task.Result); + } }