1<!DOCTYPE html>
2<!--
3Copyright (c) 2015 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7
8<link rel="import" href="/tracing/base/statistics.html">
9<link rel="import" href="/tracing/metrics/system_health/utils.html">
10<link rel="import" href="/tracing/model/user_model/animation_expectation.html">
11
12<script>
13'use strict';
14
15tr.exportTo('tr.metrics.sh', function() {
16  // The smoothness score is maximized when frame timestamp discrepancy is
17  // less than or equal to this:
18  var MIN_DISCREPANCY = 0.05;
19
20  // The smoothness score is minimized when frame timestamp discrepancy is
21  // greater than or equal to this:
22  var MAX_DISCREPANCY = 0.3;
23
24  var UNIT = tr.v.Unit.byName.normalizedPercentage_biggerIsBetter;
25
26  var DESCRIPTION = 'Mean Opinion Score for Animation smoothness';
27
28  function AnimationSmoothnessMetric(valueList, model) {
29    model.userModel.expectations.forEach(function(ue) {
30      if (!(ue instanceof tr.model.um.AnimationExpectation))
31        return;
32
33      if (ue.frameEvents === undefined ||
34          ue.frameEvents.length === 0)
35        throw new Error('Animation missing frameEvents ' + ue.stableId);
36
37      var options = {};
38      options.description = DESCRIPTION;
39
40      var groupingKeys = {};
41      groupingKeys.userExpectationStableId = ue.stableId;
42      groupingKeys.userExpectationStageTitle = ue.stageTitle;
43      groupingKeys.userExpectationInitiatorTitle = ue.initiatorTitle;
44
45      var frameTimestamps = ue.frameEvents.toArray().map(function(event) {
46        return event.start;
47      });
48
49      var absolute = false;
50      var discrepancy = tr.b.Statistics.timestampsDiscrepancy(
51          frameTimestamps, absolute);
52      var smoothness = 1 - tr.b.normalize(
53          discrepancy, MIN_DISCREPANCY, MAX_DISCREPANCY);
54      var score = tr.b.clamp(smoothness, 0, 1);
55
56      valueList.addValue(new tr.v.NumericValue(
57          model.canonicalUrlThatCreatedThisTrace, 'smoothness',
58          new tr.v.ScalarNumeric(UNIT, score),
59          options, groupingKeys));
60    });
61  }
62
63  AnimationSmoothnessMetric.prototype = {
64    __proto__: Function.prototype
65  };
66
67  tr.metrics.MetricRegistry.register(AnimationSmoothnessMetric);
68
69  return {
70    AnimationSmoothnessMetric: AnimationSmoothnessMetric
71  };
72});
73</script>
74