“ 在Android图像显示相关的开发、调试、测试过程中,如何能有效地评估画面的流畅度及监测、计算图层渲染显示的实时FPS呢?本篇文章将会提供一种实用、灵巧的思路。”
01
设计初衷
面对开发测试中遇到的卡顿掉帧问题,如何在复现卡顿的过程中持续监控FPS 和丢帧情况?特别是视频播放的场景,掉帧与FPS不稳定会带来糟糕的用户体验。因此需要有一款小工具可以实时监测图层渲染、显示的FPS变化,以便于判断是否FPS不稳定或掉帧。
02
设计原理
参考了网上现有的 FPS 计算方式原理,一定程度上满足自己的预期需求,但要么自己设计脚本计算逻辑处理,要么就要修改到源码。
方式1. 写作FPS计算脚本
基于dumpsys SurfaceFlinger --latency Layer-name或dumpsys gfxinfo获取信息,然后设计计算逻辑。
方式2. 修改SF源码呼叫computeFps
修改SurfaceFlinger的逻辑,利用原生computeFps方法来计算指定图层的FPS.
float FrameTimeline::computeFps(const std::unordered_set<int32_t>& layerIds)
那有没有其它方式呢?
当然!
我们留意到在SurfaceFlinger的源码中有一个FpsReporter,里面有提供注册监听器的接口,看起来可以利用!
class FpsReporter : public IBinder::DeathRecipient {
public:
FpsReporter(frametimeline::FrameTimeline& frameTimeline, SurfaceFlinger& flinger,
std::unique_ptr<Clock> clock = std::make_unique<SteadyClock>());
....
// Registers an Fps listener that listens to fps updates for the provided layer
void addListener(const sp<gui::IFpsListener>& listener, int32_t taskId);
// Deregisters an Fps listener
void removeListener(const sp<gui::IFpsListener>& listener);
....
}
再接着看下IFpsListener的定义,顾名思义,当fps变化时就会回调到
/frameworks/native/libs/gui/aidl/android/gui/IFpsListener.aidl
oneway interface IFpsListener {
// Reports the most recent recorded fps for the tree rooted at this layer
void onFpsReported(float fps);
}
那用户层有无提供设置的接口呢?
先看SurfaceComposerClient中的定义,确实也存在add/remove方法
/frameworks/native/libs/gui/include/gui/SurfaceComposerClient.h
static status_t addFpsListener(int32_t taskId, const sp<gui::IFpsListener>& listener);
static status_t removeFpsListener(const sp<gui::IFpsListener>& listener);
那设计