fix(companion): smooth camera preview + no flash on scanner open
ZXing TRY_HARDER (plus the inverted retry) ran on every camera frame, pegging a core — that CPU contention is what made the preview stutter. Decode attempts are now gated to ~7/s; KEEP_ONLY_LATEST drops the rest. PreviewView switches to TextureView (COMPATIBLE): the SurfaceView default punches a window hole that black-flashes inside Compose fades and ignores rounded-corner clipping. CameraQrPreview is now shared with the wallet scan modal. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
5bae8273a2
commit
1ecb5c9aa3
@ -217,13 +217,20 @@ fun QrScannerOverlay(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Shared by the pairing scanner and the wallet scan modal. */
|
||||||
@Composable
|
@Composable
|
||||||
private fun CameraQrPreview(onDecoded: (String) -> Unit) {
|
internal fun CameraQrPreview(onDecoded: (String) -> Unit) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val lifecycleOwner = LocalLifecycleOwner.current
|
val lifecycleOwner = LocalLifecycleOwner.current
|
||||||
val currentOnDecoded by rememberUpdatedState(onDecoded)
|
val currentOnDecoded by rememberUpdatedState(onDecoded)
|
||||||
val previewView = remember {
|
val previewView = remember {
|
||||||
PreviewView(context).apply { scaleType = PreviewView.ScaleType.FILL_CENTER }
|
PreviewView(context).apply {
|
||||||
|
scaleType = PreviewView.ScaleType.FILL_CENTER
|
||||||
|
// TextureView, not the SurfaceView default: SurfaceView punches a
|
||||||
|
// hole in the window, which black-flashes inside Compose fades and
|
||||||
|
// ignores rounded-corner clipping (wallet modal).
|
||||||
|
implementationMode = PreviewView.ImplementationMode.COMPATIBLE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DisposableEffect(Unit) {
|
DisposableEffect(Unit) {
|
||||||
@ -282,7 +289,19 @@ private class QrCodeAnalyzer(private val onDecoded: (String) -> Unit) : ImageAna
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var lastAttempt = 0L
|
||||||
|
|
||||||
override fun analyze(image: ImageProxy) {
|
override fun analyze(image: ImageProxy) {
|
||||||
|
// Decode ~7x/s, not on every frame: TRY_HARDER (plus the inverted
|
||||||
|
// retry) pegs a core when run at camera rate, and that CPU contention
|
||||||
|
// is what made the preview itself stutter. KEEP_ONLY_LATEST means the
|
||||||
|
// frames skipped here are simply dropped, so decodes stay current.
|
||||||
|
val now = System.currentTimeMillis()
|
||||||
|
if (now - lastAttempt < 140) {
|
||||||
|
image.close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lastAttempt = now
|
||||||
try {
|
try {
|
||||||
val plane = image.planes[0]
|
val plane = image.planes[0]
|
||||||
val buffer = plane.buffer
|
val buffer = plane.buffer
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user