为什么SurfaceFlinger在Hardware Composer中仍然每帧仍使用5ms CPU时间?

时间:2018-08-14 10:50:28

标签: android performance surfaceview systrace surfaceflinger

我正在尝试在尽可能多的android设备上以60 fps的速度运行具有挑战性和时延敏感的应用程序。它涉及到处理来自摄像机的实时帧(最好也是60 fps),并使用OpenGL ES 2/3在顶部渲染其他图形。

我首先只是尝试使用systrace和最小的测试应用程序来识别并最小化活动的任何系统级开销,该应用程序可以在SurfaceTexture中获取相机帧并将其使用OpenGL ES 2渲染到GLSurfaceView。

我一直在研究具有Android 8.0的三星Galaxy S8(Exynos版本,具有Mali GPU和4大,4小CPU设置)。

当接收摄像机帧但未渲染它们时(例如,通过将GLSurfaceView切换为RENDERMODE_WHEN_DIRTY而不是RENDERMODE_CONTINUOUSLY),则CPU使用率在整个板上显得很低,每帧CPU使用率很少,这似乎与队列的排队和出队有关SurfaceTexture。如预期的那样,当所有曲面均未更新时,SurfaceFlinger似乎无济于事。

一旦我开始渲染新帧,事情就会变得更加有趣。我的应用程序中的GLThread仅占用〜1.5ms的CPU时间,大致与我期望的差不多。出乎意料的是SurfaceFlinger中所需的CPU时间。

以下是systrace输出的一部分,通常适用于大多数帧:

SurfaceFlinger systrace

所呈现的每个帧都要经过2个SurfaceFlinger操作-有一个handleMessageInvalidate会调用updateTexImage,然后是一个主要在handleMessageRefresh中使用的doComposition,其中大多数其中postFramebuffer中花费的钱。

在大多数情况下,请注意,线程在CPU上处于活动状态,而不是处于睡眠状态。在SurfaceFlinger中花费一个内核大约需要三分之一的帧时间-如果调度程序决定对我的重要线程之一使用相同的内核,那将非常重要。

我已经阅读了很多有关SurfaceFlinger内部结构的内部文档,其中包括讨论Hardware Composer的页面:https://source.android.com/devices/graphics/arch-sf-hwc

我对HWC的理解是,合成全部在显示硬件中完成-我期望CPU方面的工作最少。只是锁存最新的缓冲区,然后将其传递给HWC。

dumpsys SurfaceFlinger确实表明HWC已用于所有层:

|    type   |  handle    | hint | flag | tr | blnd |   format    |     source crop (l,t,r,b)      |          frame         | name 
|-----------+------------+------+------+----+------+-------------+--------------------------------+------------------------+------
|       HWC | 75cee57f40 | 0000 | 0020 | 00 | 0100 | RGBx_8888   |    0.0,    0.0, 1152.0, 2960.0 |    0,    0, 1152, 2960 | SurfaceView - com.example.tangobravo.camera1test/com.example.tangobravo.camera1test.MainActivity@e16091d@3#0
|       HWC | 75cee59b40 | 0000 | 0000 | 00 | 0105 | RGBA_8888   | 1104.0,    0.0, 1440.0, 2960.0 | 1104,    0, 1440, 2960 | com.example.tangobravo.camera1test/com.example.tangobravo.camera1test.MainActivity#0
|       HWC | 75cee58100 | 0000 | 0000 | 00 | 0105 | RGBA_8888   |    0.0,    0.0,   96.0, 2960.0 | 1344,    0, 1440, 2960 | StatusBar#0
| FB TARGET | 75cee55b60 | 0000 | 0000 | 00 | 0105 | RGBA_8888   |    0.0,    0.0, 1440.0, 2960.0 |    0,    0, 1440, 2960 | HWC_FRAMEBUFFER_TARGET

那是怎么回事?为什么HWC在这里这么贵?我应该为应用程序使用更好的(更低的开销)模式吗?

我希望NEON CPU合成器能够在5毫秒左右的时间内遍历这些层,因此,就HWC而言,在CPU使用率方面似乎并没有取得太大的胜利。

0 个答案:

没有答案