Drive renderer rotation from Display.rotation, not OrientationEventListener
OrientationEventListener fires continuously on the raw accelerometer tilt and crosses the ROTATION_90 / ROTATION_270 boundary at 45° — well before the system actually rotates the activity. The renderer was swapping its texcoord buffer at 45° tilt while the GL surface and Compose layout were still in the previous orientation, so for the few degrees between "OrientationEventListener fires" and "activity rotates" the camera image rendered at the wrong rotation. Past that window it snapped back into sync. Use LocalConfiguration + Display.rotation to source the renderer's rotation. Configuration only changes when the activity has actually rotated, so the texcoord buffer flips in lock-step with the GL surface and there is no transient mis-orientation. OrientationEventListener is still used by capture for EXIF metadata. Bump to 1.1.13. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a2dfa7db3d
commit
5b553c7196
2 changed files with 20 additions and 7 deletions
|
|
@ -1,9 +1,13 @@
|
||||||
package no.naiv.tiltshift.ui
|
package no.naiv.tiltshift.ui
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.SurfaceTexture
|
import android.graphics.SurfaceTexture
|
||||||
|
import android.hardware.display.DisplayManager
|
||||||
import android.opengl.GLSurfaceView
|
import android.opengl.GLSurfaceView
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.view.Display
|
||||||
|
import android.view.Surface
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.fadeIn
|
import androidx.compose.animation.fadeIn
|
||||||
import androidx.compose.animation.fadeOut
|
import androidx.compose.animation.fadeOut
|
||||||
|
|
@ -164,11 +168,20 @@ fun CameraScreen(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward device rotation to renderer so the camera image stays
|
// Forward the activity's actual rotation (Display.rotation) to the
|
||||||
// world-aligned as the activity rotates with the device.
|
// renderer so the camera image stays world-aligned as the activity rotates
|
||||||
val currentRotation by viewModel.currentRotation.collectAsState()
|
// with the device. Don't drive this from OrientationEventListener — its
|
||||||
LaunchedEffect(currentRotation, renderer) {
|
// 45° threshold fires *before* the activity has rotated, briefly leaving
|
||||||
renderer?.setDisplayRotation(currentRotation)
|
// the texcoord set out of sync with the GL surface orientation.
|
||||||
|
// LocalConfiguration triggers a recomposition on configuration change,
|
||||||
|
// which is when Display.rotation can have changed.
|
||||||
|
val configuration = androidx.compose.ui.platform.LocalConfiguration.current
|
||||||
|
val displayRotation = remember(configuration) {
|
||||||
|
val displayManager = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
|
||||||
|
displayManager.getDisplay(Display.DEFAULT_DISPLAY)?.rotation ?: Surface.ROTATION_0
|
||||||
|
}
|
||||||
|
LaunchedEffect(displayRotation, renderer) {
|
||||||
|
renderer?.setDisplayRotation(displayRotation)
|
||||||
glSurfaceView?.requestRender()
|
glSurfaceView?.requestRender()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
versionMajor=1
|
versionMajor=1
|
||||||
versionMinor=1
|
versionMinor=1
|
||||||
versionPatch=12
|
versionPatch=13
|
||||||
versionCode=14
|
versionCode=15
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue