Why does onGloballyPosition run on the next compos...
# compose
a
Why does onGloballyPosition run on the next composition, and is there any way to get layout coords immediately?
z
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
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
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
Whatā€™s the best way to force a layout?
Or at least force this layout event?
z
What are you trying to do that you need to force a layout?
a
Iā€™m trying to display a live webrtc feed in a textureview
z
Why do you need to force a layout to do that?
a
Because it sets the dimensions of the video feed to display
This is library code
z
Sounds like you could use
onSizeChanged
for that and get the result even sooner (measurement happens before placement)
c
Either that, or use
BoxWithConstraints
to get how big the parent layout is without dealing with callbacks
z
No, i donā€™t think you need BoxWithConstraints for this, that is expensive and has a whole bunch of other implications
āž• 1
a
Was contemplating BoxWithConstraints but that seemed hacky
Exactly
Only thing is onSizeChange yields a size
z
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
onGloballyPositioned
in that screenshot is what gets called with
onGloballyPositioned
modifier
Does view layout interop nicely with with compose layout?
z
Yes
a
There is
ViewVisibility
for the view system, so if that works, Iā€™ll do it upon update
z
what is
ViewVisibility
? Iā€™ve never heard of that Oh itā€™s from that library youā€™re using?
a
Itā€™s part of livekit
yeah
šŸ˜›
onSizeChanged
also runs next composition as well, btw
z
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
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
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
The way those layout events will trigger currently is via changing of state
z
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
Uploaded in the wrong order, but thatā€™s what happens once measurements are received
z
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
Yes
The camera is on, itā€™s receiving video and transmitting
But the video feeds havent been sized appropriately
z
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
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
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
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
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
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
1513 Views