乐趣区

关于软件测试:专项测试实战-如何测试-App-流畅度基于-FPS-和丢帧率

FPS 和丢帧率能够在肯定水平上作为 APP 晦涩度的一项衡量标准,本文介绍利用 adb shell dumpsys gfxinfo 命令获取软件渲染加载过程的数据,进行计算从而获取测试后果。
在此之前,须要先理解屏幕展现绘制过程及 Android 的 VSync 机制
VSync 全称是 Vertical Synchronization(垂直同步),在 Android 4.1 中引入 Android 零碎(同时引入的一个概念是 Triple Buffering)。
学计算机的常常听到 Buffer 的概念 (生存中也碰到过很多),起到的都是一个相似的作用。用来协调两个不同速度的货色工作。
为什么会这样呢?因为 CPU/GPU 解决和屏幕展现的速度不一样然而却应用的是同一块内存。
怎么解决呢?能够将 CPU/GPU 解决和屏幕展现离开,CPU/GPU 在后盾解决,解决完一帧的数据当前才交给屏幕展现(这样可能导致另外的问题是,如果 CPU/GPU 解决很慢,那么屏幕可能会始终展现某一帧的数据,上面次要剖析这个问题的解决)。

  • 手机屏幕刷新率:手机硬件每秒刷新屏幕的次数,单位 HZ。个别是一个固定值,例如 60HZ。
  • FPS:画面每秒传输帧数,艰深来讲就是指动画或视频的画面数。单位 HZ。
    手机屏幕刷新率是固定的,FPS 则是始终变动的,怎么能力保障可能运行晦涩呢?从几个例子来看吧。
    先解释图片代表的意思:最上面黑线代表的是工夫,黄色代表屏幕展现,绿色代表 GPU 解决,蓝色代表 CPU 解决。Jank 代表的是反复展现上一帧的异样。上面会从屏幕展现的每一帧开始剖析:

上图是没有引入 VSync 机制的解决流程。

  • Display 展现第 0 帧数据,这时 CPU/GPU 会去解决第 1 帧的数据。
  • Display 展现第 1 帧数据(此时屏幕显示是失常的),这时 CPU/GPU 可能解决其余工作导致很晚才去解决绘制。
  • 因为 CPU/GPU 没解决好第 2 帧的数据,所以 Display 还是展现第 1 帧数据(此时屏幕显示是异样的),CPU/GPU 解决完第 2 帧没有解决完的数据而后持续解决第 3 帧的数据。
  • 上图中一个很显著的问题是,只有一次 CPU/GPU 解决出现异常就可能导致前面的一系列的解决出现异常。
    VSync 能够简略的认为是一种定时中断,零碎在每次须要绘制的时候都会发送 VSync Pulse 信号,CPU/GPU 收到信号后马上解决绘制。
    在 4.1 当前引入 VSync 机制。

在 FPS < 手机屏幕刷新率的状况下,所有运行完满。
VSync 机制下 Double Buffering 时 FPS > 手机屏幕刷新率的状况。

  • Display 展现第 A 帧数据,CPU/GPU 收到 VSync Pulse 信号马上解决 B 帧的数据,然而因为计算太多,导致没有在一个 VSync 距离内解决完。
  • 因为第 B 帧数据没有解决好,Display 持续展现第 A 帧数据(此时屏幕显示是异样的)。因为零碎中只存在一块内存给 CPU/GPU 解决绘制,所以在这个 VSync 距离内 cpu 不解决任何事。
  • Display 展现第 B 帧数据,CPU/GPU 收到 VSync Pulse 信号马上解决行将展现 A 帧的数据,因为计算太多,导致没有在一个 VSync 距离内解决完。
  • 须要展现的 A 帧数据没有解决好,Display 持续展现第 B 帧数据 (此时屏幕显示是异样的)。因为零碎中只存在一块内存给 CPU/GPU 解决绘制,所以在这个 VSync 距离内 CPU 不解决任何事。

    上图中一个很显著的问题是,只有呈现一次 Jank 就会影响下一次的 VSync(cpu 不能工作)。
    Triple Buffering 的引入。
  • Display 展现第 A 帧数据,CPU/GPU 收到 VSync Pulse 信号马上解决 B 帧的数据,然而因为计算太多,导致没有在一个 VSync 距离内解决完。
    因为第 B 帧数据没有筹备好,Display 持续展现第 A 帧数据(此时屏幕显示是异样的)。此时尽管 B 被 gpu 在应用,然而 cpu 能够解决 Buffer C(因为有 3 个缓冲)。
  • Display 展现第 B 帧数据,gpu 持续解决上一步骤的 C,cpu 则解决 A。
    后续过程出错的状况被升高了…
    1. 运行命令 ”adb -s ” + deviceName + ” shell dumpsys gfxinfo ” + packageName 获取根底数据,咱们会取得很多数据,这里截取须要进行剖析的局部:
    注:如果运行完命令发现无上图中的 4 个参数,则很可能是手机的“GPU 出现模式分析”未关上;
    2. 如上图信息示意了每一帧在安卓零碎中的四个阶段:
  • Draw: 示意在 Java 中创立显示列表局部中,OnDraw()办法占用的工夫
  • Prepare: 筹备工夫
  • Process:示意渲染引擎执行显示列表所花的工夫,view 越多,工夫就越长
  • Execute:示意把一帧数据发送到屏幕上排版显示理论破费的工夫,其实是理论显示帧数据的后盾缓存区与前台缓冲区替换后并将前台缓冲区的内容显示到屏幕上的工夫
  • 将下面的四个工夫加起来就是绘制一帧所须要的工夫,如果超过了 16.67 就示意掉帧了
    Android 定义了晦涩度的数据规范,以 60FPS 为规范(FPS 为每秒绘制的帧数), 帧数过小就会呈现卡顿感。
    每一帧在安卓零碎中分 4 个阶段,4 个阶段的总和超过 16.67(1 秒 60 帧, 算下来均匀 1 帧的距离就约是 16.67ms)就认为丢帧。
    这个定义在 Android6.0 以前是肯定的, 然而当初曾经没有固定的规范了,因为目前安卓零碎有 3 层缓存机制, 加上硬件上的提高, 即便超过 16.67, 也不肯定会呈现卡顿感。所以这个数据在测试时作为一种比照和绝对衡量标准,也可依据需要自定义规范。
    通过以上数据,就能够获取到每一帧的工夫、总帧数;从而就能够计算出 jank 数、vsync 数,进而就能够失去最终的 FPS 和丢帧率数据。
    当然,手工计算无疑效率低,出错率大,所以这里的计算过程最好还是以脚本模式,让代码帮咱们去计算,具体代码计算原理与专项自动化过程后续探讨。
退出移动版