Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(351)

Side by Side Diff: tools/perf/metrics/smoothness.py

Issue 200843002: Convert smoothness to the new timeline based metric API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright 2013 The Chromium Authors. All rights reserved. 1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 from metrics import Metric 5 from metrics import timeline_based_metric
6 from metrics import rendering_stats 6 from metrics import rendering_stats
7 from telemetry.page import page_measurement
8 from telemetry.page.perf_tests_helper import FlattenList 7 from telemetry.page.perf_tests_helper import FlattenList
9 from telemetry.util import statistics 8 from telemetry.util import statistics
10 from telemetry.core.timeline.model import TimelineModel 9 from telemetry.core.timeline import bounds
11
12 TIMELINE_MARKER = 'Smoothness'
13 10
14 11
15 class MissingDisplayFrameRateError(page_measurement.MeasurementFailure): 12 class SmoothnessMetric(timeline_based_metric.TimelineBasedMetric):
16 def __init__(self, name):
17 super(MissingDisplayFrameRateError, self).__init__(
18 'Missing display frame rate metrics: ' + name)
19
20 class NotEnoughFramesError(page_measurement.MeasurementFailure):
21 def __init__(self):
22 super(NotEnoughFramesError, self).__init__(
23 'Page output less than two frames')
24
25
26 class NoSupportedActionError(page_measurement.MeasurementFailure):
27 def __init__(self):
28 super(NoSupportedActionError, self).__init__(
29 'None of the actions is supported by smoothness measurement')
30
31
32 def _GetSyntheticDelayCategoriesFromPage(page):
33 if not hasattr(page, 'synthetic_delays'):
34 return []
35 result = []
36 for delay, options in page.synthetic_delays.items():
37 options = '%f;%s' % (options.get('target_duration', 0),
38 options.get('mode', 'static'))
39 result.append('DELAY(%s;%s)' % (delay, options))
40 return result
41
42
43 class SmoothnessMetric(Metric):
44 def __init__(self): 13 def __init__(self):
45 super(SmoothnessMetric, self).__init__() 14 super(SmoothnessMetric, self).__init__()
46 self._stats = None
47 self._actions = []
48 15
49 def AddActionToIncludeInMetric(self, action): 16 def AddResults(self, model, renderer_thread, interaction_record, results):
50 self._actions.append(action) 17 renderer_process = renderer_thread.parent
51 18 time_bounds = bounds.Bounds()
52 def Start(self, page, tab): 19 time_bounds.AddValue(interaction_record.start)
53 custom_categories = ['webkit.console', 'benchmark'] 20 time_bounds.AddValue(interaction_record.end)
54 custom_categories += _GetSyntheticDelayCategoriesFromPage(page) 21 stats = rendering_stats.RenderingStats(
55 tab.browser.StartTracing(','.join(custom_categories), 60) 22 renderer_process, model.browser_process, [time_bounds])
56 tab.ExecuteJavaScript('console.time("' + TIMELINE_MARKER + '")') 23 if stats.mouse_wheel_scroll_latency:
57 if tab.browser.platform.IsRawDisplayFrameRateSupported():
58 tab.browser.platform.StartRawDisplayFrameRateMeasurement()
59
60 def Stop(self, page, tab):
61 if tab.browser.platform.IsRawDisplayFrameRateSupported():
62 tab.browser.platform.StopRawDisplayFrameRateMeasurement()
63 tab.ExecuteJavaScript('console.timeEnd("' + TIMELINE_MARKER + '")')
64 tracing_timeline_data = tab.browser.StopTracing()
65 timeline_model = TimelineModel(timeline_data=tracing_timeline_data)
66 timeline_ranges = [ action.GetActiveRangeOnTimeline(timeline_model)
67 for action in self._actions ]
68
69 renderer_process = timeline_model.GetRendererProcessFromTab(tab)
70 self._stats = rendering_stats.RenderingStats(
71 renderer_process, timeline_model.browser_process, timeline_ranges)
72
73 if not self._stats.frame_times:
74 raise NotEnoughFramesError()
75
76 def AddResults(self, tab, results):
77 if self._stats.mouse_wheel_scroll_latency:
78 mean_mouse_wheel_scroll_latency = statistics.ArithmeticMean( 24 mean_mouse_wheel_scroll_latency = statistics.ArithmeticMean(
79 self._stats.mouse_wheel_scroll_latency) 25 stats.mouse_wheel_scroll_latency)
80 mouse_wheel_scroll_latency_discrepancy = statistics.DurationsDiscrepancy( 26 mouse_wheel_scroll_latency_discrepancy = statistics.DurationsDiscrepancy(
81 self._stats.mouse_wheel_scroll_latency) 27 stats.mouse_wheel_scroll_latency)
82 results.Add('mean_mouse_wheel_scroll_latency', 'ms', 28 results.Add('mean_mouse_wheel_scroll_latency', 'ms',
83 round(mean_mouse_wheel_scroll_latency, 3)) 29 round(mean_mouse_wheel_scroll_latency, 3))
84 results.Add('mouse_wheel_scroll_latency_discrepancy', '', 30 results.Add('mouse_wheel_scroll_latency_discrepancy', '',
85 round(mouse_wheel_scroll_latency_discrepancy, 4)) 31 round(mouse_wheel_scroll_latency_discrepancy, 4))
86 32
87 if self._stats.touch_scroll_latency: 33 if stats.touch_scroll_latency:
88 mean_touch_scroll_latency = statistics.ArithmeticMean( 34 mean_touch_scroll_latency = statistics.ArithmeticMean(
89 self._stats.touch_scroll_latency) 35 stats.touch_scroll_latency)
90 touch_scroll_latency_discrepancy = statistics.DurationsDiscrepancy( 36 touch_scroll_latency_discrepancy = statistics.DurationsDiscrepancy(
91 self._stats.touch_scroll_latency) 37 stats.touch_scroll_latency)
92 results.Add('mean_touch_scroll_latency', 'ms', 38 results.Add('mean_touch_scroll_latency', 'ms',
93 round(mean_touch_scroll_latency, 3)) 39 round(mean_touch_scroll_latency, 3))
94 results.Add('touch_scroll_latency_discrepancy', '', 40 results.Add('touch_scroll_latency_discrepancy', '',
95 round(touch_scroll_latency_discrepancy, 4)) 41 round(touch_scroll_latency_discrepancy, 4))
96 42
97 if self._stats.js_touch_scroll_latency: 43 if stats.js_touch_scroll_latency:
98 mean_js_touch_scroll_latency = statistics.ArithmeticMean( 44 mean_js_touch_scroll_latency = statistics.ArithmeticMean(
99 self._stats.js_touch_scroll_latency) 45 stats.js_touch_scroll_latency)
100 js_touch_scroll_latency_discrepancy = statistics.DurationsDiscrepancy( 46 js_touch_scroll_latency_discrepancy = statistics.DurationsDiscrepancy(
101 self._stats.js_touch_scroll_latency) 47 stats.js_touch_scroll_latency)
102 results.Add('mean_js_touch_scroll_latency', 'ms', 48 results.Add('mean_js_touch_scroll_latency', 'ms',
103 round(mean_js_touch_scroll_latency, 3)) 49 round(mean_js_touch_scroll_latency, 3))
104 results.Add('js_touch_scroll_latency_discrepancy', '', 50 results.Add('js_touch_scroll_latency_discrepancy', '',
105 round(js_touch_scroll_latency_discrepancy, 4)) 51 round(js_touch_scroll_latency_discrepancy, 4))
106 52
107 # List of raw frame times. 53 # List of raw frame times.
108 frame_times = FlattenList(self._stats.frame_times) 54 frame_times = FlattenList(stats.frame_times)
109 results.Add('frame_times', 'ms', frame_times) 55 results.Add('frame_times', 'ms', frame_times)
110 56
111 # Arithmetic mean of frame times. 57 # Arithmetic mean of frame times.
112 mean_frame_time = statistics.ArithmeticMean(frame_times) 58 mean_frame_time = statistics.ArithmeticMean(frame_times)
113 results.Add('mean_frame_time', 'ms', round(mean_frame_time, 3)) 59 results.Add('mean_frame_time', 'ms', round(mean_frame_time, 3))
114 60
115 # Absolute discrepancy of frame time stamps. 61 # Absolute discrepancy of frame time stamps.
116 frame_discrepancy = statistics.TimestampsDiscrepancy( 62 frame_discrepancy = statistics.TimestampsDiscrepancy(
117 self._stats.frame_timestamps) 63 stats.frame_timestamps)
118 results.Add('jank', 'ms', round(frame_discrepancy, 4)) 64 results.Add('jank', 'ms', round(frame_discrepancy, 4))
119 65
120 # Are we hitting 60 fps for 95 percent of all frames? 66 # Are we hitting 60 fps for 95 percent of all frames?
121 # We use 19ms as a somewhat looser threshold, instead of 1000.0/60.0. 67 # We use 19ms as a somewhat looser threshold, instead of 1000.0/60.0.
122 percentile_95 = statistics.Percentile(frame_times, 95.0) 68 percentile_95 = statistics.Percentile(frame_times, 95.0)
123 results.Add('mostly_smooth', 'score', 1.0 if percentile_95 < 19.0 else 0.0) 69 results.Add('mostly_smooth', 'score', 1.0 if percentile_95 < 19.0 else 0.0)
124
125 if tab.browser.platform.IsRawDisplayFrameRateSupported():
126 for r in tab.browser.platform.GetRawDisplayFrameRateMeasurements():
127 if r.value is None:
128 raise MissingDisplayFrameRateError(r.name)
129 results.Add(r.name, r.unit, r.value)
OLDNEW
« no previous file with comments | « tools/perf/measurements/timeline_based_measurement_unittest.py ('k') | tools/perf/metrics/smoothness_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698