相关疑难解决方法(0)

设置视图的绝对位置

是否可以在Android中设置视图的绝对位置?(我知道有一个AbsoluteLayout,但它被弃用了......)

例如,如果我有一个240x320px的屏幕,我怎么能添加一个ImageView20x20px,使其中心位于(100,100)?

layout android position view android-layout

177
推荐指数
4
解决办法
24万
查看次数

最小化Android GLSurfaceView滞后

关于Stack Overflow的其他一些问题,我已经从这里阅读了Android Surfaces,SurfaceViews等内部指南:

https://source.android.com/devices/graphics/architecture.html

该指南让我对Android上所有不同部分的组合方式有了更好的理解.它介绍了eglSwapBuffers如何将渲染帧推送到队列中,当它准备下一帧显示时,SurfaceFlinger将使用该队列.如果队列已满,那么它将等到缓冲区在返回之前可用于下一帧.上面的文档将其描述为"填充队列"并依赖交换缓冲区的"反压"来限制渲染到显示的vsync.这是使用GLSurfaceView的默认连续渲染模式发生的情况.

如果你的渲染是简单的并且在比帧周期少得多的情况下完成,那么这是由BufferQueue引起的额外延迟,因为SwapBuffers上的等待直到队列满了才发生,因此我们'重新渲染始终位于队列的后面,因此不会立即显示在下一个vsync上,因为队列中可能存在缓冲区.

相比之下,按需渲染的发生频率通常比显示更新速率低得多,因此通常这些视图的BufferQueues为空,因此推送到这些队列的任何更新都将被SurfaceFlinger在下一个vsync上抓取.

所以问题在于:如何设置连续渲染器,但延迟最小?目标是每个vsync开始时缓冲区队列为空,我在16ms内渲染我的内容,将其推送到队列(缓冲区计数= 1),然后由SurfaceFlinger在下一个vsync(缓冲区计数)上使用它= 0),重复一遍.队列中的缓冲区数量可以在systrace中看到,因此目标是在0和1之间交替使用.

我上面提到的文档介绍了Choreographer作为在每个vsync上获得回调的方法.但是我不相信这足以让我能够实现我追求的最小滞后行为.我已经测试了在vsync回调上使用非常小的onDrawFrame()执行requestRender(),它确实展示了0/1缓冲区计数行为.但是,如果SurfaceFlinger无法在一个帧周期内完成所有工作(可能是通知弹出或其他),该怎么办?在这种情况下,我希望我的渲染器很乐意为每个vsync生成1帧,但该BufferQueue的消费者端已经丢弃了一帧.结果:我们现在在队列中交替使用1到2个缓冲区,并且我们在渲染和查看帧之间获得了一段滞后.

该文档似乎建议查看报告的vsync时间与回调运行时间之间的时间偏差.我可以看到,如果你的回调由于你的主线程由于布局传递或其他东西而延迟传递,那会有什么帮助.但是我认为这不会允许检测到SurfaceFlinger跳过节拍并且不能消耗帧.应用程序是否有任何方法可以解决SurfaceFlinger丢帧的问题?似乎无法告诉队列的长度打破了使用vsync时间进行游戏状态更新的想法,因为在您实际渲染的渲染之前,队列中存在未知数量的帧.

减少队列的最大长度并依赖背压将是实现此目的的一种方法,但我认为没有API来设置GLSurfaceView BufferQueue中的最大缓冲区数量?

android lag surfaceview

25
推荐指数
1
解决办法
5155
查看次数

标签 统计

android ×2

android-layout ×1

lag ×1

layout ×1

position ×1

surfaceview ×1

view ×1