Status Update
Comments
po...@google.com <po...@google.com>
po...@google.com <po...@google.com> #2
ch...@google.com <ch...@google.com>
ch...@google.com <ch...@google.com> #3
Great! Thanks a lot, I'll look for the live updates soon!
po...@google.com <po...@google.com> #4
Thank you Charcoal for looking at this. FYI one more report for a similar issue:
ch...@google.com <ch...@google.com> #5
This is a redraw timing related issue which happens when using PreviewView
's SurfaceViewImplementation
mode together with Compose UI
.
Based on the PointerGun
sample project provide in bindPreview()
call, the preview stretched issue disappeared.
Original code:
PreviewView(context).apply {
setBackgroundColor(Color.GREEN)
layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
scaleType = PreviewView.ScaleType.FILL_CENTER
post {
cameraProviderFuture.addListener(Runnable {
val cameraProvider = cameraProviderFuture.get()
bindPreview(
cameraProvider,
lifecycleOwner,
this,
)
}, ContextCompat.getMainExecutor(context))
}
}
New code:
PreviewView(context).apply {
setBackgroundColor(Color.GREEN)
post {
cameraProviderFuture.addListener(Runnable {
val cameraProvider = cameraProviderFuture.get()
bindPreview(
cameraProvider,
lifecycleOwner,
this,
)
// Updated layoutParams and ScaleType after bindPreview() call
layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
scaleType = PreviewView.ScaleType.FILL_CENTER
}, ContextCompat.getMainExecutor(context))
}
}
But, the above solution won't work if the compose related library version is updated from 1.0.0-beta03
to 1.0.0-beta09
.
I also tried to add onClickListener
to the PreviewView
and change its ScaleType
. The preview can be displayed correctly if ScaleType
is changed to a different type when receiving a click event. It means that the SurfaceViewImplementation's transformation calculation should be correct and the issue might be caused by calling setScaleX/Y
and setTranslationX/Y
too early.
PreviewView(context).apply {
setBackgroundColor(Color.GREEN)
layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
scaleType = PreviewView.ScaleType.FILL_CENTER
// Adds onClickListener to change its ScaleType
setOnClickListener { v ->
if (scaleType == PreviewView.ScaleType.FILL_CENTER) {
scaleType = PreviewView.ScaleType.FIT_CENTER
} else {
scaleType = PreviewView.ScaleType.FILL_CENTER
}
}
post {
cameraProviderFuture.addListener(Runnable {
val cameraProvider = cameraProviderFuture.get()
bindPreview(
cameraProvider,
lifecycleOwner,
this,
)
}, ContextCompat.getMainExecutor(context))
}
}
The setScaleX/Y
and setTranslationX/Y
only called after surfaceCreated
event is received. But the issue still exists.
You must ensure that the drawing thread only touches the underlying Surface while it is valid -- between SurfaceHolder.Callback.surfaceCreated() and SurfaceHolder.Callback.surfaceDestroyed().
After the surface is created, it will provide the surface to the SurfaceRequest
requested by the PreviewView
's SurfaceProvider
. Therefore, I tried to only call setScaleX/Y
and setTranslationX/Y
when the surface has been provided. I found the issue disappeared by this change. This might be the solution for this issue and this might also be a reasonable timing to start calling setScaleX/Y
and setTranslationX/Y
since the preview content can be displayed only if the surface has been provided.
ap...@google.com <ap...@google.com> #6
Branch: androidx-main
commit ed384c5a0be359b021a2eeb76fc92ebb3676ee18
Author: Charcoal Chen <charcoalchen@google.com>
Date: Thu Jun 24 09:03:33 2021
Fixed PreviewView PERFORMANCE mode stretch issue when using together with Compose UI
This is a timing issue. When using PreviewView's SurfaceViewImplementation mode, the images inside the SurfaceView won't be scaled/translated to match the SurfaceView's dimensions if calling setScaleX/Y or setTranslationX/Y functions too early. This issue doesn't exist when not using PreviewView's SurfaceViewImplementation mode together with Compose UI. This issue doesn't occur if calling setScaleX/Y or setTranslationX/Y functions after SurfaceView's surface has been provided. This should be reasonable timing since the preview content can be displayed only if the surface has been provided.
Relnote: "Fixed PreviewView PERFORMANCE mode stretch issue when using together with Compose UI."
Bug: 183864890
Test: ./gradlew camera:camera-view:build && ./gradlew camera:camera-view:connectedAndroidTest && manual test
Change-Id: Ie11371e57cb196552cef786c5567ddb60187fdca
M camera/camera-view/src/main/java/androidx/camera/view/PreviewViewImplementation.java
ap...@google.com <ap...@google.com> #7
Branch: androidx-main
commit da4a0aed64df0e9636956738162c727195eadcf8
Author: Charcoal Chen <charcoalchen@google.com>
Date: Fri Jun 25 14:42:57 2021
Add new ComposeUiFragment into the view test app
This is a simple fragment to easily check whether preview will be stretched when using PreveiwView together with Compose UI.
Bug: 183864890
Test: ./gradlew camera:integration-tests:camera-testapp-view:build && ./gradlew camera:integration-tests:camera-testapp-view:connectedAndroidTest && manual test
Change-Id: I79a45baf2b80b04dac8b28442fdf407ca3f32b89
M camera/integration-tests/viewtestapp/build.gradle
A camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/ComposeUiFragment.kt
M camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/MainActivity.java
M camera/integration-tests/viewtestapp/src/main/res/menu/actionbar_menu.xml
M camera/integration-tests/viewtestapp/src/main/res/values/donottranslate-strings.xml
ch...@google.com <ch...@google.com> #8
The solution has been merged in
ch...@google.com <ch...@google.com> #9
Update some more information. After doing more testing for this issue, this issue looks only happen on Android 10 and 11 devices.
Attached PointerGun-Original.apk is built by the original CameraX library setting.
Attached PointerGun-BuiltWithSolution.apk is built by the local verifying library with the solution.
API Level | Android Version | Device Name | Issue Occur |
---|---|---|---|
30 | 11 | Moto One Hyper | Yes |
30 | 11 | Samsung S20+ | Yes |
29 | 10 | Samsung Note 10+ | Yes |
28 | 9 | Samsung Note 10+ | No |
28 | 9 | Moto G7 | No |
27 | 8.1 | Samsung J2 Core | No |
26 | 8.0 | Samsung S8+ | No |
25 | 7.1.1 | Samsung Note 8 | No |
ch...@google.com <ch...@google.com> #10
Hi Mihai,
Could you also help to double check this issue in the Compose UI part? It is because that:
- The issue doesn't happen when using only CameraX's PreviewView (SurfaceViewImplementation mode).
- As mentioned in
, the same code might have the issue when usingcomment#5 1.0.0-beta09
but doesn't have the issue when using1.0.0-beta03
.
If the issue could also possibly have a solution in the Compose UI side, it will benefit the applications which have their own SurfaceView widget implementation and use it together with Compose UI. Or, maybe we can know what we should take care of when using SurfaceView together with Compose UI.
Description
Component used: androidx.compose.ui:ui Version used: 1.0.0-beta03 Devices/Android versions reproduced on:
The camera image appears stretched and only one half is shown. Note that the view occupies the expected amount of space, so maybe the bug lies within cameraX. Works fine in landscape orientation.
Sample project and screenshot are attached.