从Grafika 问题跟踪器中反省一下:
弹跳球是软件渲染的,所以任何占用 CPU 时间的东西都会让它变慢。在具有中等 CPU 和大显示器的设备(例如 Nexus 10)上,它永远不会接近 60fps。所以当你玩导航栏时减速并不让我感到惊讶,但如果即使你停止使用导航栏后它仍然很慢,那就有点奇怪了。
视频播放应该受到的影响较小,因为这对 CPU 的影响较小。
对此类问题的调查通常从使用systrace捕获处于“好”和“坏”状态的跟踪并比较两者开始。
BufferQueue“异步模式”的关键在于,如果消费者跟不上生产者,允许丢帧。它主要用于 SurfaceTexture,其中生产者和消费者在同一个应用程序中,可能在同一个线程上,因此让生产者停止等待消费者可能会导致程序挂起。我不确定你需要它超过 60fps 是什么意思,但我猜你在显示器上扔帧的速度比渲染它们的速度要快......所以你并没有真正提高帧速率,你是只需使用 BufferQueue 来丢弃帧,而不是使用 Choreographer 来决定何时需要自己丢弃它们。
无论如何,我在 2014 年 6 月离开谷歌,早在 Lollipop 完成之前。如果某些东西在 KitKat 上正常工作,但在 Lollipop 上却很奇怪,恐怕我无法提供太多见解。如果您可以轻松重现该行为,则可能值得捕获演示问题的视频(将第二部智能手机指向出现问题的设备,以便他们可以看到您如何操作设备)并在http:/上提交错误/b.android.com/。
OP上传的一些痕迹:
查看 kitkat 跟踪,SurfaceFlinger 中发生了一些奇怪的事情。主线程postFrameBuffer
等待很长时间(23-32ms)。它最终醒来,CPU 行表明它正在等待来自我不熟悉的“galcore 守护进程”的活动(似乎特别适用于 Vivante GPU)。
棒棒糖跟踪仅显示 CPU 行,就好像捕获是在没有必要标签的情况下完成的。我不相信 systrace capture 命令在 kitkat 和 lollipop 之间发生了显着变化,所以我很困惑为什么用户空间启动的日志记录会消失,但内核线程调度的东西会保留。确保您已sched gfx view
指定。
较新的棒棒糖痕迹只有大约一秒钟的良好数据。当您看到“未完成”时,这意味着“开始”记录没有匹配的“结束”记录。-b
您可以使用该标志增加 systrace 日志记录缓冲区大小。我认为那里已经足够了。
查看该/system/bin/surfaceflinger
行,您可以看到,在“良好”跟踪中,postFrameBuffer
通常在大约 16 毫秒内完成,但它仍在等待 galcore。放大 388 毫秒(使用 WASD 键)。在 388.196ms 时,在 CPU 2 行上,你可以看到 galcore 在做一些事情。完成后,surfaceflinger 行顶部的细线从浅灰色(睡眠)变为绿色(运行)。在 388.548 毫秒,再次在 CPU 2 上,galcore 再次运行,然后在 Surfaceflinger 行上您看到queueBuffer
开始执行。
“坏”的痕迹看起来是一样的。例如,您可以在 101.146ms 和 101.666ms 看到两次 galcore 执行,在 surfaceflinger 行上似乎有类似的效果。关键区别在于花费的时间postFrameBuffer
,“好”大约为 16 毫秒,“坏”大约为 30 毫秒。
所以这似乎不是行为转变。相反,事情需要更长的时间,并且会错过最后期限。
据我所知,SurfaceFlinger 被 galcore 守护进程阻止。在“好”和“坏”的情况下都是如此。要查看时间应该是什么样子,您可以在 Nexus 设备上运行 systrace,或与其他设备的跟踪进行比较(例如,本案例研究中的那个或这个 SO 问题)。如果放大,您可以看到doComposition
在几毫秒内执行,并postFrameBuffer
在十分之几毫秒内完成。
总结:没有好坏之分,有坏有坏。:-) 我不知道 galcore 是什么,但您可能需要与 GPU OEM 进行对话。