From de57966458a0a0d564d46697c2a63b6a2de672a4 Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Wed, 6 May 2026 12:57:56 +0200 Subject: [PATCH 1/2] added a comment --- src/Sentry.Unity/ScreenshotEventProcessor.cs | 36 +++++++++++++------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/Sentry.Unity/ScreenshotEventProcessor.cs b/src/Sentry.Unity/ScreenshotEventProcessor.cs index d9416205c..b97ea94bb 100644 --- a/src/Sentry.Unity/ScreenshotEventProcessor.cs +++ b/src/Sentry.Unity/ScreenshotEventProcessor.cs @@ -13,9 +13,13 @@ public class ScreenshotEventProcessor : ISentryEventProcessor private readonly ISentryMonoBehaviour _sentryMonoBehaviour; private volatile int _isCapturingScreenshot; - public ScreenshotEventProcessor(SentryUnityOptions sentryOptions) : this(sentryOptions, SentryMonoBehaviour.Instance) { } + public ScreenshotEventProcessor(SentryUnityOptions sentryOptions) + : this(sentryOptions, SentryMonoBehaviour.Instance) { } - internal ScreenshotEventProcessor(SentryUnityOptions sentryOptions, ISentryMonoBehaviour sentryMonoBehaviour) + internal ScreenshotEventProcessor( + SentryUnityOptions sentryOptions, + ISentryMonoBehaviour sentryMonoBehaviour + ) { _options = sentryOptions; _sentryMonoBehaviour = sentryMonoBehaviour; @@ -27,6 +31,9 @@ public SentryEvent Process(SentryEvent @event) if (Interlocked.CompareExchange(ref _isCapturingScreenshot, 1, 0) == 0) { _options.LogDebug("Starting coroutine to capture a screenshot."); + // Capture must run on the main thread after WaitForEndOfFrame (ReadPixels needs a complete frame), but the + // event processor pipeline is synchronous and may run on any thread - blocking here would deadlock when + // called from the main thread. So we capture in a coroutine and ship the screenshot as a separate envelope. _sentryMonoBehaviour.QueueCoroutine(CaptureScreenshotCoroutine(@event)); } @@ -73,15 +80,19 @@ internal IEnumerator CaptureScreenshotCoroutine(SentryEvent @event) var screenshotBytes = screenshot.EncodeToJPG(_options.ScreenshotCompression); if (screenshotBytes is null || screenshotBytes.Length == 0) { - _options.LogWarning("Screenshot capture returned empty data for event {0}", @event.EventId); + _options.LogWarning( + "Screenshot capture returned empty data for event {0}", + @event.EventId + ); yield break; } var attachment = new SentryAttachment( - AttachmentType.Default, - new ByteAttachmentContent(screenshotBytes), - "screenshot.jpg", - "image/jpeg"); + AttachmentType.Default, + new ByteAttachmentContent(screenshotBytes), + "screenshot.jpg", + "image/jpeg" + ); _options.LogDebug("Screenshot captured for event {0}", @event.EventId); @@ -102,12 +113,11 @@ internal IEnumerator CaptureScreenshotCoroutine(SentryEvent @event) } } - internal virtual Texture2D CreateNewScreenshotTexture2D(SentryUnityOptions options) - => SentryScreenshot.CreateNewScreenshotTexture2D(options); + internal virtual Texture2D CreateNewScreenshotTexture2D(SentryUnityOptions options) => + SentryScreenshot.CreateNewScreenshotTexture2D(options); - internal virtual void CaptureAttachment(SentryId eventId, SentryAttachment attachment) - => (Sentry.SentrySdk.CurrentHub as Hub)?.CaptureAttachment(eventId, attachment); + internal virtual void CaptureAttachment(SentryId eventId, SentryAttachment attachment) => + (Sentry.SentrySdk.CurrentHub as Hub)?.CaptureAttachment(eventId, attachment); - internal virtual YieldInstruction WaitForEndOfFrame() - => new WaitForEndOfFrame(); + internal virtual YieldInstruction WaitForEndOfFrame() => new WaitForEndOfFrame(); } From cc9622c42b37df0b6d6cb702ab2ea568bec10400 Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Wed, 6 May 2026 13:15:31 +0200 Subject: [PATCH 2/2] fixed formatting --- src/Sentry.Unity/ScreenshotEventProcessor.cs | 33 ++++++++------------ 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/src/Sentry.Unity/ScreenshotEventProcessor.cs b/src/Sentry.Unity/ScreenshotEventProcessor.cs index b97ea94bb..c00d2b705 100644 --- a/src/Sentry.Unity/ScreenshotEventProcessor.cs +++ b/src/Sentry.Unity/ScreenshotEventProcessor.cs @@ -13,13 +13,9 @@ public class ScreenshotEventProcessor : ISentryEventProcessor private readonly ISentryMonoBehaviour _sentryMonoBehaviour; private volatile int _isCapturingScreenshot; - public ScreenshotEventProcessor(SentryUnityOptions sentryOptions) - : this(sentryOptions, SentryMonoBehaviour.Instance) { } + public ScreenshotEventProcessor(SentryUnityOptions sentryOptions) : this(sentryOptions, SentryMonoBehaviour.Instance) { } - internal ScreenshotEventProcessor( - SentryUnityOptions sentryOptions, - ISentryMonoBehaviour sentryMonoBehaviour - ) + internal ScreenshotEventProcessor(SentryUnityOptions sentryOptions, ISentryMonoBehaviour sentryMonoBehaviour) { _options = sentryOptions; _sentryMonoBehaviour = sentryMonoBehaviour; @@ -80,19 +76,15 @@ internal IEnumerator CaptureScreenshotCoroutine(SentryEvent @event) var screenshotBytes = screenshot.EncodeToJPG(_options.ScreenshotCompression); if (screenshotBytes is null || screenshotBytes.Length == 0) { - _options.LogWarning( - "Screenshot capture returned empty data for event {0}", - @event.EventId - ); + _options.LogWarning("Screenshot capture returned empty data for event {0}", @event.EventId); yield break; } var attachment = new SentryAttachment( - AttachmentType.Default, - new ByteAttachmentContent(screenshotBytes), - "screenshot.jpg", - "image/jpeg" - ); + AttachmentType.Default, + new ByteAttachmentContent(screenshotBytes), + "screenshot.jpg", + "image/jpeg"); _options.LogDebug("Screenshot captured for event {0}", @event.EventId); @@ -113,11 +105,12 @@ internal IEnumerator CaptureScreenshotCoroutine(SentryEvent @event) } } - internal virtual Texture2D CreateNewScreenshotTexture2D(SentryUnityOptions options) => - SentryScreenshot.CreateNewScreenshotTexture2D(options); + internal virtual Texture2D CreateNewScreenshotTexture2D(SentryUnityOptions options) + => SentryScreenshot.CreateNewScreenshotTexture2D(options); - internal virtual void CaptureAttachment(SentryId eventId, SentryAttachment attachment) => - (Sentry.SentrySdk.CurrentHub as Hub)?.CaptureAttachment(eventId, attachment); + internal virtual void CaptureAttachment(SentryId eventId, SentryAttachment attachment) + => (Sentry.SentrySdk.CurrentHub as Hub)?.CaptureAttachment(eventId, attachment); - internal virtual YieldInstruction WaitForEndOfFrame() => new WaitForEndOfFrame(); + internal virtual YieldInstruction WaitForEndOfFrame() + => new WaitForEndOfFrame(); }