https://kotlinlang.org logo
#compose
Title
# compose
a

andrew

07/20/2022, 6:34 PM
Why does onGloballyPosition run on the next composition, and is there any way to get layout coords immediately?
z

Zach Klippenstein (he/him) [MOD]

07/20/2022, 6:52 PM
onPlaced
should give you the coordinates before the drawing phase of the current frame. I think it might even do so before the placement phase of your children., but I'm not sure.
a

andrew

07/20/2022, 6:53 PM
I tried that once, I think, lemme check again
Working on a hackathon thing at work, a smart video callbox with livekit 😛
Using compose for android, and compose multiplatform on ubuntu core for the box
Still seems to do it on next composition
z

Zach Klippenstein (he/him) [MOD]

07/20/2022, 7:00 PM
It won't be available in composition until the next frame, because the layout and draw phases happen after the composition phase completes. So you can get it in the same frame, but there's no way to get it for the same composition - trying to do so means you're probably doing something in composition that should be done in a later phase.
a

andrew

07/20/2022, 7:08 PM
What’s the best way to force a layout?
Or at least force this layout event?
z

Zach Klippenstein (he/him) [MOD]

07/20/2022, 7:09 PM
What are you trying to do that you need to force a layout?
a

andrew

07/20/2022, 7:09 PM
I’m trying to display a live webrtc feed in a textureview
z

Zach Klippenstein (he/him) [MOD]

07/20/2022, 7:10 PM
Why do you need to force a layout to do that?
a

andrew

07/20/2022, 7:14 PM
Because it sets the dimensions of the video feed to display
This is library code
z

Zach Klippenstein (he/him) [MOD]

07/20/2022, 7:18 PM
Sounds like you could use
onSizeChanged
for that and get the result even sooner (measurement happens before placement)
c

Casey Brooks

07/20/2022, 7:19 PM
Either that, or use
BoxWithConstraints
to get how big the parent layout is without dealing with callbacks
z

Zach Klippenstein (he/him) [MOD]

07/20/2022, 7:20 PM
No, i don’t think you need BoxWithConstraints for this, that is expensive and has a whole bunch of other implications
1
a

andrew

07/20/2022, 7:20 PM
Was contemplating BoxWithConstraints but that seemed hacky
Exactly
Only thing is onSizeChange yields a size
z

Zach Klippenstein (he/him) [MOD]

07/20/2022, 7:22 PM
I don’t know how this
ComposeVisibility
class interacts with everything else. But because `AndroidView`’s
update
function runs before layout, you could probably store the view somewhere then tell it what size to use from the
onSizeChanged
callback. Or, subclass the view and just make that call directly inside the view’s measurement callback.
Because it sets the dimensions of the video feed to display
I assumed you just needed a size since “dimensions” usually implies size, not location.
a

andrew

07/20/2022, 7:23 PM
onGloballyPositioned
in that screenshot is what gets called with
onGloballyPositioned
modifier
Does view layout interop nicely with with compose layout?
z

Zach Klippenstein (he/him) [MOD]

07/20/2022, 7:24 PM
Yes
a

andrew

07/20/2022, 7:24 PM
There is
ViewVisibility
for the view system, so if that works, I’ll do it upon update
z

Zach Klippenstein (he/him) [MOD]

07/20/2022, 7:25 PM
what is
ViewVisibility
? I’ve never heard of that Oh it’s from that library you’re using?
a

andrew

07/20/2022, 7:26 PM
It’s part of livekit
yeah
😛
onSizeChanged
also runs next composition as well, btw
z

Zach Klippenstein (he/him) [MOD]

07/20/2022, 7:34 PM
Yes, the first composition that sees its value will be the one in the next frame. It's important to understand that composition isn't the only thing that happens in a compose ui frame though. It's the first of a few discreet phases that always happen in the same order.
The onSizeChanged callback is invoked as soon as the node it's registered on is measured. This happens before anything is placed in that layout pass, and before anything is drawn.
a

andrew

07/20/2022, 7:37 PM
I understand that, yes
I guess my assumption is, that those modifiers notify of layout changes, it would fire off an event which you could then recompose afterwards for
But I see how that could also cause a loop, potentially
z

Zach Klippenstein (he/him) [MOD]

07/20/2022, 7:39 PM
You can, but it doesn't change the ordering of the phases. After composition is done for the frame, it won't run again until the next frame (except for subcompositions potentially, which is a whole other can of worms)
🪱 1
a

andrew

07/20/2022, 7:40 PM
The way those layout events will trigger currently is via changing of state
z

Zach Klippenstein (he/him) [MOD]

07/20/2022, 7:40 PM
In most cases, the only things measurement should affect are layout and drawing. In your case, idk when the library needs to know the size, but if it needs to know before the view has been measured you're gonna have a bad time no matter what 😅
a

andrew

07/20/2022, 7:41 PM
Uploaded in the wrong order, but that’s what happens once measurements are received
z

Zach Klippenstein (he/him) [MOD]

07/20/2022, 7:42 PM
Also note that measurement, placement, drawing, and even AndroidView update blocks all have their own snapshot state observers, so any states that are read in those contexts will invalidate the corresponding phase for the next frame.
You're saying the first frame is effectively blank?
a

andrew

07/20/2022, 7:44 PM
Yes
The camera is on, it’s receiving video and transmitting
But the video feeds havent been sized appropriately
z

Zach Klippenstein (he/him) [MOD]

07/20/2022, 7:59 PM
So the library determines the size of the video feeds by querying that
size
method on VideoSinkVisibility? When does it do that?
Or are you pushing the size to the library somehow, eg via a setter?
a

andrew

07/20/2022, 8:01 PM
Internally it uses an observer from what I can tell,
notifyChanged
should trigger an update
But, we pass in layout info using
onGloballyPositioned
, both kinds, the modifier, and the method from the library
c

Chris Fillmore

07/20/2022, 11:07 PM
I’m not really familiar with LiveKit but I assume you’re using this TextureViewRenderer? https://github.com/livekit/client-sdk-android/blob/main/livekit-android-sdk/src/main/java/io/livekit/android/renderer/TextureViewRenderer.kt Have you tried using
org.webrtc.SurfaceViewRenderer
? (making this change would have other implications but I’m curious if it would solve your problem)
a

andrew

07/20/2022, 11:24 PM
Yes, I have
Whether or not it's a surface view or texture view doesn't really have any implications it's just whether or not it's drawn as a view or not, which the traditional view system supports anyway, and compose interops nicely
c

Chris Fillmore

07/20/2022, 11:42 PM
The difference is just in how the video is drawn. You’re seeing some delay in when frames are drawn? Does SurfaceViewRenderer have the same problem? This might be useful reading https://source.android.com/devices/graphics/architecture.html#high_level This also https://stackoverflow.com/questions/21305651/textureview-vs-glsurfaceview-or-how-to-use-glsurfaceview-with-egl14#21322600 Basically TextureView is a little slower than SurfaceView. All this might make no difference. I’m building a webrtc app using compose and I’ve had to go down the graphics architecture rabbit hole a bit for some features. Good luck
a

andrew

07/21/2022, 12:48 PM
That's what I was saying but oversimplified for brevity sake haha
Both work, but after the first composition, perfectly infact. It's just a layout issue
👍 1
1163 Views