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

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 def AddResults(self, model, renderer_thread, interaction_record, results):
50 self._actions.append(action) 29 renderer_process = renderer_thread.parent
51 30 time_bounds = bounds.Bounds()
52 def Start(self, page, tab): 31 time_bounds.AddValue(interaction_record.start)
53 custom_categories = ['webkit.console', 'benchmark'] 32 time_bounds.AddValue(interaction_record.end)
54 custom_categories += _GetSyntheticDelayCategoriesFromPage(page) 33 stats = rendering_stats.RenderingStats(
55 tab.browser.StartTracing(','.join(custom_categories), 60) 34 renderer_process, model.browser_process, [time_bounds])
56 tab.ExecuteJavaScript('console.time("' + TIMELINE_MARKER + '")') 35 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( 36 mean_mouse_wheel_scroll_latency = statistics.ArithmeticMean(
79 self._stats.mouse_wheel_scroll_latency, 37 stats.mouse_wheel_scroll_latency,
80 len(self._stats.mouse_wheel_scroll_latency)) 38 len(stats.mouse_wheel_scroll_latency))
81 mouse_wheel_scroll_latency_discrepancy = statistics.DurationsDiscrepancy( 39 mouse_wheel_scroll_latency_discrepancy = statistics.DurationsDiscrepancy(
82 self._stats.mouse_wheel_scroll_latency) 40 stats.mouse_wheel_scroll_latency)
83 results.Add('mean_mouse_wheel_scroll_latency', 'ms', 41 results.Add('mean_mouse_wheel_scroll_latency', 'ms',
84 round(mean_mouse_wheel_scroll_latency, 3)) 42 round(mean_mouse_wheel_scroll_latency, 3))
85 results.Add('mouse_wheel_scroll_latency_discrepancy', '', 43 results.Add('mouse_wheel_scroll_latency_discrepancy', '',
86 round(mouse_wheel_scroll_latency_discrepancy, 4)) 44 round(mouse_wheel_scroll_latency_discrepancy, 4))
87 45
88 if self._stats.touch_scroll_latency: 46 if stats.touch_scroll_latency:
89 mean_touch_scroll_latency = statistics.ArithmeticMean( 47 mean_touch_scroll_latency = statistics.ArithmeticMean(
90 self._stats.touch_scroll_latency, 48 stats.touch_scroll_latency,
91 len(self._stats.touch_scroll_latency)) 49 len(stats.touch_scroll_latency))
92 touch_scroll_latency_discrepancy = statistics.DurationsDiscrepancy( 50 touch_scroll_latency_discrepancy = statistics.DurationsDiscrepancy(
93 self._stats.touch_scroll_latency) 51 stats.touch_scroll_latency)
94 results.Add('mean_touch_scroll_latency', 'ms', 52 results.Add('mean_touch_scroll_latency', 'ms',
95 round(mean_touch_scroll_latency, 3)) 53 round(mean_touch_scroll_latency, 3))
96 results.Add('touch_scroll_latency_discrepancy', '', 54 results.Add('touch_scroll_latency_discrepancy', '',
97 round(touch_scroll_latency_discrepancy, 4)) 55 round(touch_scroll_latency_discrepancy, 4))
98 56
99 if self._stats.js_touch_scroll_latency: 57 if stats.js_touch_scroll_latency:
100 mean_js_touch_scroll_latency = statistics.ArithmeticMean( 58 mean_js_touch_scroll_latency = statistics.ArithmeticMean(
101 self._stats.js_touch_scroll_latency, 59 stats.js_touch_scroll_latency,
102 len(self._stats.js_touch_scroll_latency)) 60 len(stats.js_touch_scroll_latency))
103 js_touch_scroll_latency_discrepancy = statistics.DurationsDiscrepancy( 61 js_touch_scroll_latency_discrepancy = statistics.DurationsDiscrepancy(
104 self._stats.js_touch_scroll_latency) 62 stats.js_touch_scroll_latency)
105 results.Add('mean_js_touch_scroll_latency', 'ms', 63 results.Add('mean_js_touch_scroll_latency', 'ms',
106 round(mean_js_touch_scroll_latency, 3)) 64 round(mean_js_touch_scroll_latency, 3))
107 results.Add('js_touch_scroll_latency_discrepancy', '', 65 results.Add('js_touch_scroll_latency_discrepancy', '',
108 round(js_touch_scroll_latency_discrepancy, 4)) 66 round(js_touch_scroll_latency_discrepancy, 4))
109 67
110 # List of raw frame times. 68 # List of raw frame times.
111 frame_times = FlattenList(self._stats.frame_times) 69 frame_times = FlattenList(stats.frame_times)
112 results.Add('frame_times', 'ms', frame_times) 70 results.Add('frame_times', 'ms', frame_times)
113 71
114 # Arithmetic mean of frame times. 72 # Arithmetic mean of frame times.
115 mean_frame_time = statistics.ArithmeticMean(frame_times, 73 mean_frame_time = statistics.ArithmeticMean(frame_times,
116 len(frame_times)) 74 len(frame_times))
117 results.Add('mean_frame_time', 'ms', round(mean_frame_time, 3)) 75 results.Add('mean_frame_time', 'ms', round(mean_frame_time, 3))
118 76
119 # Absolute discrepancy of frame time stamps. 77 # Absolute discrepancy of frame time stamps.
120 frame_discrepancy = statistics.TimestampsDiscrepancy( 78 frame_discrepancy = statistics.TimestampsDiscrepancy(
121 self._stats.frame_timestamps) 79 stats.frame_timestamps)
122 results.Add('jank', 'ms', round(frame_discrepancy, 4)) 80 results.Add('jank', 'ms', round(frame_discrepancy, 4))
123 81
124 # Are we hitting 60 fps for 95 percent of all frames? 82 # 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. 83 # We use 19ms as a somewhat looser threshold, instead of 1000.0/60.0.
nduca 2014/03/12 18:07:24 lets file a followup bug and cc:you cc:ernstm to l
126 percentile_95 = statistics.Percentile(frame_times, 95.0) 84 percentile_95 = statistics.Percentile(frame_times, 95.0)
127 results.Add('mostly_smooth', 'score', 1.0 if percentile_95 < 19.0 else 0.0) 85 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
« 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