Skip to content

Read the zoom range once per bound camera instead of on every frame - #647

Merged
temcguir merged 3 commits into
mainfrom
temcguir/zoom-range-cache
Nov 10, 2026
Merged

temcguir merged 3 commits into
mainfrom
temcguir/zoom-range-cache

Conversation

@temcguir

@temcguir temcguir commented Nov 10, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Fixes a slow camera restart and stalled captures when a camera extension session is active (for example, Night Mode from #609).

The preview capture callback in CameraSession.updateCameraStateWithCaptureResults read CameraInfo.zoomState on every capture result to clamp the target zoom ratio. For an extension session, CameraX computes zoomState by querying the extension's characteristics (SessionProcessor.getExtensionZoomRange → CameraExtensionCharacteristics) on each call. On the device tested, doing this at preview frame rate saturates the CameraX camera thread. That thread also completes still captures and opens and closes the camera, so work queues up behind the callbacks.

The zoom range doesn't change while a camera is bound, so it is now read once per bound camera and reused. A new preview use case, and so a new callback, is created for each bound camera, so the cached range starts fresh after a lens or sub-mode change. If zoomState isn't available yet, it is read again on the next frame, as before.

The per-frame read was added in #625.

Measurements

With Night Mode selected on a Pixel device: capture a photo, open the post-capture screen, then go back.

Before After
Night capture Did not complete within 12 s; failed when the camera stopped Saved in 3.3 s
Camera close when opening post-capture 13–38 s 1.0 s
Back to camera running again 30–49 s 0.65 s

Testing

  • :core:camera:testDebugUnitTest
  • Manual on-device timing above.

The preview capture callback read CameraInfo.zoomState on every capture
result to clamp the target zoom ratio. For a camera extension session,
zoomState queries the extension's characteristics through the vendor
extension service on each call. At preview frame rate this saturates the
CameraX camera thread, which also completes still captures and opens and
closes the camera, so captures stall and the camera takes tens of seconds
to close and reopen.

The zoom range doesn't change while a camera is bound, so read it once
and reuse it.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request optimizes zoom state reading in CameraSession.kt by caching the zoomRange instead of querying it on every frame, which prevents backing up the camera thread during camera extension sessions. The feedback suggests a performance improvement to avoid unnecessary ClosedFloatingPointRange object allocations in the high-frequency preview frame path by refactoring the coerceIn logic.

@temcguir
temcguir merged commit 4d7fee7 into main Nov 10, 2026
12 checks passed
@temcguir
temcguir deleted the temcguir/zoom-range-cache branch November 10, 2026 00:54
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.

3 participants