utils.dart 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import 'dart:collection';
  2. import 'dart:ui';
  3. import 'package:flutter/scheduler.dart';
  4. /// 单位换算
  5. int byte2MB(int bytes) {
  6. return (bytes / 1024 / 1024).round();
  7. }
  8. // 需监听fps时注册
  9. void startFPSListener() {
  10. SchedulerBinding.instance?.addTimingsCallback(_onReportTimings);
  11. }
  12. // 不需监听时移除
  13. void stopFPSListener() {
  14. SchedulerBinding.instance?.removeTimingsCallback(_onReportTimings);
  15. }
  16. const maxframes = 100; // 100 帧足够了,对于 60 fps 来说
  17. final lastFrames = ListQueue<FrameTiming>(maxframes);
  18. const refreshRate = 60;
  19. const frameInterval =
  20. Duration(microseconds: Duration.microsecondsPerSecond ~/ 60);
  21. void _onReportTimings(List<FrameTiming> timings) {
  22. // 把 Queue 当作堆栈用
  23. for (FrameTiming timing in timings) {
  24. lastFrames.addFirst(timing);
  25. }
  26. // 只保留 maxframes
  27. while (lastFrames.length > maxframes) {
  28. lastFrames.removeLast();
  29. }
  30. }
  31. double get getScreenFPS {
  32. var lastFramesSet = <FrameTiming>[];
  33. for (FrameTiming timing in lastFrames) {
  34. if (lastFramesSet.isEmpty) {
  35. lastFramesSet.add(timing);
  36. } else {
  37. var lastStart =
  38. lastFramesSet.last.timestampInMicroseconds(FramePhase.buildStart);
  39. if (lastStart - timing.timestampInMicroseconds(FramePhase.rasterFinish) >
  40. (frameInterval.inMicroseconds * 2)) {
  41. // in different set
  42. break;
  43. }
  44. lastFramesSet.add(timing);
  45. }
  46. }
  47. var framesCount = lastFramesSet.length;
  48. var costCount = lastFramesSet.map((t) {
  49. // 耗时超过 frameInterval 会导致丢帧
  50. return (t.totalSpan.inMicroseconds ~/ frameInterval.inMicroseconds) + 1;
  51. }).fold<int>(0, (a, b) => a + b);
  52. return framesCount * refreshRate / costCount;
  53. }