From f0d81db06887c4b2c894302fc5b8c15897ea66b8 Mon Sep 17 00:00:00 2001 From: Ole-Morten Duesund Date: Mon, 11 May 2026 14:05:45 +0200 Subject: [PATCH] Fix landscape preview by rebinding on rotation change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `Preview.targetRotation = …` on an already-bound use case does not refresh the live SurfaceTexture's transform matrix or trigger a new SurfaceRequest with a rotation-appropriate buffer size — the new rotation only applies to subsequently bound streams. With our custom SurfaceProvider, the result was that rotating to landscape left the camera still writing portrait-oriented frames into the now-landscape GL surface, so the preview appeared to rotate with the device instead of switching to landscape. Rebind the camera use cases when the target rotation changes so CameraX fires a fresh SurfaceRequest with the correct resolution and matrix. Also revert the OrientationDetector mapping back to its original (matches Display.rotation for a fullSensor activity, which is what setTargetRotation expects); the previous "fix" went the wrong direction and was not the root cause. Bump to 1.1.8. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../java/no/naiv/tiltshift/camera/CameraManager.kt | 14 +++++++++----- .../no/naiv/tiltshift/util/OrientationDetector.kt | 10 ++-------- version.properties | 4 ++-- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/no/naiv/tiltshift/camera/CameraManager.kt b/app/src/main/java/no/naiv/tiltshift/camera/CameraManager.kt index b6f659d..7f7bed5 100644 --- a/app/src/main/java/no/naiv/tiltshift/camera/CameraManager.kt +++ b/app/src/main/java/no/naiv/tiltshift/camera/CameraManager.kt @@ -194,15 +194,19 @@ class CameraManager(private val context: Context) { /** * Updates the target rotation for Preview and ImageCapture use cases. - * Call when the device rotates: this rotates the SurfaceTexture transform matrix - * (so the GL preview stays upright) and tags captures with the right orientation. - * Safe to call on the main thread; CameraX permits live target-rotation updates. + * + * Rebinds the use cases so CameraX issues a fresh SurfaceRequest with a + * resolution matching the new rotation and a corresponding texture transform + * matrix. Calling `preview.targetRotation = rotation` alone is insufficient + * for a custom SurfaceProvider — the new rotation only takes effect on + * subsequently bound streams, leaving the live SurfaceTexture matrix and + * buffer size stale (which made the preview appear locked to the original + * portrait orientation when the device was rotated to landscape). */ fun setTargetRotation(rotation: Int) { if (targetRotation == rotation) return targetRotation = rotation - preview?.targetRotation = rotation - imageCapture?.targetRotation = rotation + lifecycleOwnerRef?.get()?.let { bindCameraUseCases(it) } } /** diff --git a/app/src/main/java/no/naiv/tiltshift/util/OrientationDetector.kt b/app/src/main/java/no/naiv/tiltshift/util/OrientationDetector.kt index 45bcf3a..f7b49da 100644 --- a/app/src/main/java/no/naiv/tiltshift/util/OrientationDetector.kt +++ b/app/src/main/java/no/naiv/tiltshift/util/OrientationDetector.kt @@ -24,17 +24,11 @@ class OrientationDetector(private val context: Context) { override fun onOrientationChanged(orientation: Int) { if (orientation == ORIENTATION_UNKNOWN) return - // OrientationEventListener reports the device's physical rotation - // (clockwise from natural). Surface.ROTATION_* describes the screen's - // logical rotation, which is the opposite direction — so device tilted - // 90° CW (orientation ≈ 90, "left side at top") maps to ROTATION_270, - // and 90° CCW (orientation ≈ 270) maps to ROTATION_90. Matches the - // CameraX docs example for setTargetRotation. val rotation = when { orientation >= 315 || orientation < 45 -> Surface.ROTATION_0 - orientation >= 45 && orientation < 135 -> Surface.ROTATION_270 + orientation >= 45 && orientation < 135 -> Surface.ROTATION_90 orientation >= 135 && orientation < 225 -> Surface.ROTATION_180 - else -> Surface.ROTATION_90 + else -> Surface.ROTATION_270 } if (rotation != lastRotation) { diff --git a/version.properties b/version.properties index 0f86d43..dd2cc78 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ versionMajor=1 versionMinor=1 -versionPatch=7 -versionCode=9 +versionPatch=8 +versionCode=10