FPS帧率统计工具

从trace和录屏能算出大致帧率,更准确的帧率数据还需要从代码中统计

为了评估流畅度是否好,要计算1s 实际绘制的帧数,空闲不绘制的帧数,所以最好用2个帧率:

一个是满帧fps,一个是实际绘制fps,

好处是相比Surfaceflinger统计消费App生成的Buffer数量,可以从2个fps知道发现低于60帧,是真的掉帧了,还是没有绘制不是掉帧

如:doFrame ran 60 times (Real:34) 表示实际只绘制了34帧,但是可以绘制到60帧

实现原理:

在Choreographer的doFrame方法中加入一个计数器mFrameCount;当doFrame方法被调用时+1(mFrameCount++),启动1个Timer,1秒打印一个次logcat

每次doframe之后强制调用scheduleVsyncLocked()接受vsync,记录强制注册vsync的doFrame次数用变量mFrameMuteCount记录

但是统计不到Surfaceview(视频和地图),可以通过命令查看最近128帧内平均fps

dumpsys SurfaceFlinger --latency {layer_name}

输出结果:SurfaceView[renderframe]在最近128帧内平均fps: 29.88

使用方法:python fps.py com.map/com.map.MainActivity#0

dumpsys SurfaceFlinger --latency原理是:

https://cs.android.com/android/platform/superproject/+/master:frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

# prints some information about the last 128 frames displayed in # that window.The data returned looks like this: # 16954612 # 7657467895508 7657482691352 7657493499756 # (...) # # The first line is the refresh period of the HWC(vsync,here 16.95 ms)(e.g. 60hz->16.6ms 90hz->11.1ms) # 1st) app-vsync (fps.py get this value) # 2st) HWC-vsync # 3st) timestamp after SF submitted frame to the HWC # The difference between the 1st and 3rd timestamp is the frame-latency. # An interesting data is when the frame latency crosses a refresh period # boundary, this can be calculated this way: # # ceil((C - A) / refresh-period) # # (each time the number above changes, we have a "jank"). # If this happens a lot during an animation, the animation appears # janky, even if it runs at 60 fps in average void SurfaceFlinger::dumpStatsLocked(const DumpArgs& args, std::string& result) const { StringAppendF(&result, "%" PRId64 "\n", getVsyncPeriodFromHWC()); if (args.size() > 1) { const auto name = String8(args[1]); mCurrentState.traverseInZOrder([&](Layer* layer) { if (layer->getName() == name.string()) { layer->dumpFrameStats(result); } }); } else { mAnimFrameTracker.dumpStats(result); } }

其它统计方式:

  • window.addOnFrameMetricsAvailableListener 性能好,数据全,关键是找好接入时机

(官方推荐统计方式 https://zhuanlan.zhihu.com/p/619383056

  • adb shell dumpsys gfxinfo com.demo framestats 从应用生成的最近120个帧中输出带有纳秒时间戳的帧时间信息

好的,下面是回答: 要在Android上实现实时统计帧率工具,你可以使用Choreographer类来完成。Choreographer是一个系统级别的类,用于控制UI渲染的流程。通过使用Choreographer,您可以在UI线程上更新帧率计数器并将其显示在UI上。 具体实现步骤如下: 1.创建一个自定义View,以便在屏幕上显示当前帧速率。 2.使用Choreographer.postFrameCallback()注册一个回调,该回调将在每个新帧可用时调用。 3.在回调中,您将进行一些操作,如更新帧速率统计信息并将其发送到UI线程以进行显示。 示例代码如下: public class FPSView extends View implements Choreographer.FrameCallback { private final static long ONE_SEC_NANOS = 1000000000L; private Choreographer mChoreographer; private long mPrevFrameTimeNanos; private int mFrameCount; private Paint mPaint; public FPSView(Context context) { super(context); mChoreographer = Choreographer.getInstance(); mPaint = new Paint(); mPaint.setColor(Color.RED); mPaint.setTextSize(50); } public FPSView(Context context, AttributeSet attrs) { super(context, attrs); mChoreographer = Choreographer.getInstance(); mPaint = new Paint(); mPaint.setColor(Color.RED); mPaint.setTextSize(50); } @Override public void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawText("FPS: " + mFrameCount, 30, getHeight() - 30, mPaint); mChoreographer.postFrameCallback(this); } @Override public void doFrame(long frameTimeNanos) { if (mPrevFrameTimeNanos != 0) { long frameDurationNanos = frameTimeNanos - mPrevFrameTimeNanos; double frameRate = ONE_SEC_NANOS / (double)frameDurationNanos; mFrameCount = (int)Math.round(frameRate); invalidate(); } mPrevFrameTimeNanos = frameTimeNanos; mChoreographer.postFrameCallback(this); } } 在这里,我们使用Choreographer的postFrameCallback()方法在每个渲染帧之后安排一个回调。回调接收一个参数--时间戳--表示当前帧的时间,以纳秒为单位。通过跟踪帧的持续时间并计算平均帧速率,我们更新帧速率统计信息,然后调用View.invalidate()重新绘制。 注意,在上面的示例中,我们在onDraw()方法中调用了postFrameCallback()。这是因为重绘视图是Choreographer在某些设备上安排的回调触发的事件之一。所以我们必须始终在每个渲染帧完成后重新调度下一个回调。 以上是在Android上实现实时统计帧率工具的基本思路和示例代码。希望对您有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值