metrics_util.cc 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/public/cpp/metrics_util.h"
  5. #include "base/bind.h"
  6. #include "base/check.h"
  7. #include "base/no_destructor.h"
  8. #include "ui/compositor/scoped_animation_duration_scale_mode.h"
  9. namespace ash {
  10. namespace metrics_util {
  11. namespace {
  12. bool g_data_collection_enabled = false;
  13. std::vector<cc::FrameSequenceMetrics::CustomReportData>& GetDataCollector() {
  14. static base::NoDestructor<
  15. std::vector<cc::FrameSequenceMetrics::CustomReportData>>
  16. data;
  17. return *data;
  18. }
  19. void CollectDataAndForwardReport(
  20. ReportCallback callback,
  21. const cc::FrameSequenceMetrics::CustomReportData& data) {
  22. // An arbitrary cap on the maximum number of animations being collected.
  23. DCHECK_LT(GetDataCollector().size(), 1000u);
  24. GetDataCollector().push_back(data);
  25. std::move(callback).Run(data);
  26. }
  27. // Calculates smoothness from |throughput| and sends to |callback|.
  28. void ForwardSmoothness(SmoothnessCallback callback,
  29. const cc::FrameSequenceMetrics::CustomReportData& data) {
  30. bool animation_in_test =
  31. ui::ScopedAnimationDurationScaleMode::duration_multiplier() !=
  32. ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION;
  33. // Do not report if tracker is started and stopped closely in time.
  34. // There are 2 cases:
  35. // * frame_expected == 0
  36. // when there is no BeginFrame between start and stop.
  37. // * frame_expected == 1 && frames_produced == 0
  38. // when there is one BeginFrame but no frame generated between
  39. // start and stop; should not included this case in tests.
  40. if (!data.frames_expected ||
  41. (!animation_in_test && data.frames_expected == 1 &&
  42. data.frames_produced == 0)) {
  43. return;
  44. }
  45. callback.Run(CalculateSmoothness(data));
  46. }
  47. } // namespace
  48. ReportCallback ForSmoothness(SmoothnessCallback callback,
  49. bool exclude_from_data_collection) {
  50. auto forward_smoothness =
  51. base::BindRepeating(&ForwardSmoothness, std::move(callback));
  52. if (!g_data_collection_enabled || exclude_from_data_collection)
  53. return forward_smoothness;
  54. return base::BindRepeating(&CollectDataAndForwardReport,
  55. std::move(forward_smoothness));
  56. }
  57. void StartDataCollection() {
  58. DCHECK(!g_data_collection_enabled);
  59. g_data_collection_enabled = true;
  60. }
  61. std::vector<cc::FrameSequenceMetrics::CustomReportData> StopDataCollection() {
  62. DCHECK(g_data_collection_enabled);
  63. g_data_collection_enabled = false;
  64. std::vector<cc::FrameSequenceMetrics::CustomReportData> data;
  65. data.swap(GetDataCollector());
  66. return data;
  67. }
  68. int CalculateSmoothness(
  69. const cc::FrameSequenceMetrics::CustomReportData& data) {
  70. DCHECK(data.frames_expected);
  71. return std::floor(100.0f * data.frames_produced / data.frames_expected);
  72. }
  73. int CalculateJank(const cc::FrameSequenceMetrics::CustomReportData& data) {
  74. DCHECK(data.frames_expected);
  75. return std::floor(100.0f * data.jank_count / data.frames_expected);
  76. }
  77. } // namespace metrics_util
  78. } // namespace ash