Skip to content

fix(replay): Prevent concurrent PixelCopy frame access#5808

Draft
romtsn wants to merge 1 commit into
mainfrom
rz/fix/pixelcopy-frame-race
Draft

fix(replay): Prevent concurrent PixelCopy frame access#5808
romtsn wants to merge 1 commit into
mainfrom
rz/fix/pixelcopy-frame-race

Conversation

@romtsn

@romtsn romtsn commented Jul 21, 2026

Copy link
Copy Markdown
Member

📜 Description

Prevent concurrent access to the bitmap shared by PixelCopy and replay processing.

The strategy now drops a capture while another frame is in flight, keeps the gate held through
masking and SurfaceView compositing, suppresses last-frame emission during that work, and defers
bitmap cleanup until the outstanding PixelCopy callback completes.

💡 Motivation and Context

PixelCopy.request() returns before RenderThread finishes writing its destination. The replay
executor could therefore draw masks or SurfaceView content into the same bitmap, while close()
could recycle it before the asynchronous request completed. This could produce torn or improperly
masked frames and may contribute to native libhwui crashes.

Dropping an overlapping frame avoids blocking the main thread or allocating a second recording
bitmap.

Fixes #5340
Refs JAVA-490

💚 How did you test it?

  • ./gradlew ':sentry-android-replay:testDebugUnitTest' --tests='*PixelCopyStrategyTest*' --info
  • ./gradlew spotlessApply apiDump

Added regression coverage for requests overlapping PixelCopy, queued masking, last-frame emission,
and cleanup during an outstanding request.

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.
  • Public API changes reviewed by another Mobile SDK team member or implemented according to the develop docs spec.

🔮 Next steps

  • Harden capture submission around Window and SurfaceView lifecycle transitions separately.
  • Consider restoring RGB_565 when SurfaceView capture is disabled in a separate change.

Keep PixelCopy, masking, compositing, and cleanup from accessing the shared bitmap concurrently.

Fixes GH-5340

Co-Authored-By: Codex <noreply@openai.com>
@linear-code

linear-code Bot commented Jul 21, 2026

Copy link
Copy Markdown

JAVA-490

@github-actions

Copy link
Copy Markdown
Contributor
Fails
🚫 Please consider adding a changelog entry for the next release.

Instructions and example for changelog

Please add an entry to CHANGELOG.md to the "Unreleased" section. Make sure the entry includes this PR's number.

Example:

## Unreleased

### Fixes

- Prevent concurrent PixelCopy frame access ([#5808](https://github.com/getsentry/sentry-java/pull/5808))

If none of the above apply, you can opt out of this check by adding #skip-changelog to the PR description or adding a skip-changelog label.

Generated by 🚫 dangerJS against 45c33ca

@sentry

sentry Bot commented Jul 21, 2026

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
SDK Size io.sentry.tests.size 8.49.0 (1) release

⚙️ sentry-android Build Distribution Settings

@github-actions

Copy link
Copy Markdown
Contributor

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 313.33 ms 371.69 ms 58.35 ms
Size 0 B 0 B 0 B

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
5b1a06b 352.27 ms 413.70 ms 61.43 ms
2124a46 319.19 ms 415.04 ms 95.85 ms
ad8da22 314.52 ms 352.47 ms 37.95 ms
d15471f 304.55 ms 408.43 ms 103.87 ms
0ee65e9 317.37 ms 366.50 ms 49.13 ms
2195398 351.77 ms 433.22 ms 81.45 ms
ee747ae 358.21 ms 389.41 ms 31.20 ms
abfcc92 309.54 ms 380.32 ms 70.78 ms
8558cac 306.16 ms 355.24 ms 49.09 ms
d15471f 310.26 ms 377.04 ms 66.78 ms

App size

Revision Plain With Sentry Diff
5b1a06b 0 B 0 B 0 B
2124a46 1.58 MiB 2.12 MiB 551.51 KiB
ad8da22 1.58 MiB 2.29 MiB 719.83 KiB
d15471f 1.58 MiB 2.13 MiB 559.54 KiB
0ee65e9 0 B 0 B 0 B
2195398 0 B 0 B 0 B
ee747ae 1.58 MiB 2.10 MiB 530.95 KiB
abfcc92 1.58 MiB 2.13 MiB 557.31 KiB
8558cac 0 B 0 B 0 B
d15471f 1.58 MiB 2.13 MiB 559.54 KiB

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.

Session Replay: race between PixelCopy.request and executor compositing/masking on shared screenshot bitmap

1 participant