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

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

Issue 170183004: Move smoothness to the new API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@submit
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 metrics import statistics 7 from metrics import statistics
8 from telemetry.core.timeline import bounds
8 from telemetry.page import page_measurement 9 from telemetry.page import page_measurement
9 from telemetry.page.perf_tests_helper import FlattenList 10 from telemetry.page.perf_tests_helper import FlattenList
10 from telemetry.core.timeline.model import TimelineModel
11 11
12 TIMELINE_MARKER = 'Smoothness'
13
14
15 class MissingDisplayFrameRateError(page_measurement.MeasurementFailure):
16 def __init__(self, name):
17 super(MissingDisplayFrameRateError, self).__init__(
18 'Missing display frame rate metrics: ' + name)
19 12
20 class NotEnoughFramesError(page_measurement.MeasurementFailure): 13 class NotEnoughFramesError(page_measurement.MeasurementFailure):
21 def __init__(self): 14 def __init__(self):
22 super(NotEnoughFramesError, self).__init__( 15 super(NotEnoughFramesError, self).__init__(
23 'Page output less than two frames') 16 'Page output less than two frames')
24 17
25 18
26 class NoSupportedActionError(page_measurement.MeasurementFailure): 19 class NoSupportedActionError(page_measurement.MeasurementFailure):
27 def __init__(self): 20 def __init__(self):
28 super(NoSupportedActionError, self).__init__( 21 super(NoSupportedActionError, self).__init__(
29 'None of the actions is supported by smoothness measurement') 22 'None of the actions is supported by smoothness measurement')
30 23
31 24 class SmoothnessMetric(timeline_based_metric.TimelineBasedMetric):
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): 25 def __init__(self):
45 super(SmoothnessMetric, self).__init__() 26 super(SmoothnessMetric, self).__init__()
46 self._stats = None
47 self._actions = []
48 27
49 def AddActionToIncludeInMetric(self, action): 28 @timeline_based_metric.WrapResults
50 self._actions.append(action) 29 def AddResults(self, model, renderer_thread, interaction_record, results):
51 30 renderer_process = renderer_thread.parent
52 def Start(self, page, tab): 31 time_bounds = bounds.Bounds()
53 custom_categories = ['webkit.console', 'benchmark'] 32 time_bounds.AddValue(interaction_record.start)
54 custom_categories += _GetSyntheticDelayCategoriesFromPage(page) 33 time_bounds.AddValue(interaction_record.end)
55 tab.browser.StartTracing(','.join(custom_categories), 60) 34 stats = rendering_stats.RenderingStats(
56 tab.ExecuteJavaScript('console.time("' + TIMELINE_MARKER + '")') 35 renderer_process, model.browser_process, [time_bounds])
57 if tab.browser.platform.IsRawDisplayFrameRateSupported(): 36 if stats.mouse_wheel_scroll_latency:
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( 37 mean_mouse_wheel_scroll_latency = statistics.ArithmeticMean(
79 self._stats.mouse_wheel_scroll_latency, 38 stats.mouse_wheel_scroll_latency,
80 len(self._stats.mouse_wheel_scroll_latency)) 39 len(stats.mouse_wheel_scroll_latency))
81 mouse_wheel_scroll_latency_discrepancy = statistics.DurationsDiscrepancy( 40 mouse_wheel_scroll_latency_discrepancy = statistics.DurationsDiscrepancy(
82 self._stats.mouse_wheel_scroll_latency) 41 stats.mouse_wheel_scroll_latency)
83 results.Add('mean_mouse_wheel_scroll_latency', 'ms', 42 results.Add('mean_mouse_wheel_scroll_latency', 'ms',
84 round(mean_mouse_wheel_scroll_latency, 3)) 43 round(mean_mouse_wheel_scroll_latency, 3))
85 results.Add('mouse_wheel_scroll_latency_discrepancy', '', 44 results.Add('mouse_wheel_scroll_latency_discrepancy', '',
86 round(mouse_wheel_scroll_latency_discrepancy, 4)) 45 round(mouse_wheel_scroll_latency_discrepancy, 4))
87 46
88 if self._stats.touch_scroll_latency: 47 if stats.touch_scroll_latency:
89 mean_touch_scroll_latency = statistics.ArithmeticMean( 48 mean_touch_scroll_latency = statistics.ArithmeticMean(
90 self._stats.touch_scroll_latency, 49 stats.touch_scroll_latency,
91 len(self._stats.touch_scroll_latency)) 50 len(stats.touch_scroll_latency))
92 touch_scroll_latency_discrepancy = statistics.DurationsDiscrepancy( 51 touch_scroll_latency_discrepancy = statistics.DurationsDiscrepancy(
93 self._stats.touch_scroll_latency) 52 stats.touch_scroll_latency)
94 results.Add('mean_touch_scroll_latency', 'ms', 53 results.Add('mean_touch_scroll_latency', 'ms',
95 round(mean_touch_scroll_latency, 3)) 54 round(mean_touch_scroll_latency, 3))
96 results.Add('touch_scroll_latency_discrepancy', '', 55 results.Add('touch_scroll_latency_discrepancy', '',
97 round(touch_scroll_latency_discrepancy, 4)) 56 round(touch_scroll_latency_discrepancy, 4))
98 57
99 if self._stats.js_touch_scroll_latency: 58 if stats.js_touch_scroll_latency:
100 mean_js_touch_scroll_latency = statistics.ArithmeticMean( 59 mean_js_touch_scroll_latency = statistics.ArithmeticMean(
101 self._stats.js_touch_scroll_latency, 60 stats.js_touch_scroll_latency,
102 len(self._stats.js_touch_scroll_latency)) 61 len(stats.js_touch_scroll_latency))
103 js_touch_scroll_latency_discrepancy = statistics.DurationsDiscrepancy( 62 js_touch_scroll_latency_discrepancy = statistics.DurationsDiscrepancy(
104 self._stats.js_touch_scroll_latency) 63 stats.js_touch_scroll_latency)
105 results.Add('mean_js_touch_scroll_latency', 'ms', 64 results.Add('mean_js_touch_scroll_latency', 'ms',
106 round(mean_js_touch_scroll_latency, 3)) 65 round(mean_js_touch_scroll_latency, 3))
107 results.Add('js_touch_scroll_latency_discrepancy', '', 66 results.Add('js_touch_scroll_latency_discrepancy', '',
108 round(js_touch_scroll_latency_discrepancy, 4)) 67 round(js_touch_scroll_latency_discrepancy, 4))
109 68
110 # List of raw frame times. 69 # List of raw frame times.
111 frame_times = FlattenList(self._stats.frame_times) 70 frame_times = FlattenList(stats.frame_times)
112 results.Add('frame_times', 'ms', frame_times) 71 results.Add('frame_times', 'ms', frame_times)
113 72
114 # Arithmetic mean of frame times. 73 # Arithmetic mean of frame times.
115 mean_frame_time = statistics.ArithmeticMean(frame_times, 74 mean_frame_time = statistics.ArithmeticMean(frame_times,
116 len(frame_times)) 75 len(frame_times))
117 results.Add('mean_frame_time', 'ms', round(mean_frame_time, 3)) 76 results.Add('mean_frame_time', 'ms', round(mean_frame_time, 3))
118 77
119 # Absolute discrepancy of frame time stamps. 78 # Absolute discrepancy of frame time stamps.
120 frame_discrepancy = statistics.TimestampsDiscrepancy( 79 frame_discrepancy = statistics.TimestampsDiscrepancy(
121 self._stats.frame_timestamps) 80 stats.frame_timestamps)
122 results.Add('jank', 'ms', round(frame_discrepancy, 4)) 81 results.Add('jank', 'ms', round(frame_discrepancy, 4))
123 82
124 # Are we hitting 60 fps for 95 percent of all frames? 83 # Are we hitting 60 fps for 95 percent of all frames?
125 # We use 19ms as a somewhat looser threshold, instead of 1000.0/60.0. 84 # We use 19ms as a somewhat looser threshold, instead of 1000.0/60.0.
126 percentile_95 = statistics.Percentile(frame_times, 95.0) 85 percentile_95 = statistics.Percentile(frame_times, 95.0)
127 results.Add('mostly_smooth', 'score', 1.0 if percentile_95 < 19.0 else 0.0) 86 results.Add('mostly_smooth', 'score', 1.0 if percentile_95 < 19.0 else 0.0)
128
129 if tab.browser.platform.IsRawDisplayFrameRateSupported():
130 for r in tab.browser.platform.GetRawDisplayFrameRateMeasurements():
131 if r.value is None:
132 raise MissingDisplayFrameRateError(r.name)
133 results.Add(r.name, r.unit, r.value)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698