| Index: tools/perf/metrics/smoothness.py
|
| diff --git a/tools/perf/metrics/smoothness.py b/tools/perf/metrics/smoothness.py
|
| index 44176c7076eaac9e1a673dea44390b27b2fcb837..28c9ab244114850d8e04ec1aa6fb3ed3b2e66834 100644
|
| --- a/tools/perf/metrics/smoothness.py
|
| +++ b/tools/perf/metrics/smoothness.py
|
| @@ -2,110 +2,56 @@
|
| # Use of this source code is governed by a BSD-style license that can be
|
| # found in the LICENSE file.
|
|
|
| -from metrics import Metric
|
| +from metrics import timeline_based_metric
|
| from metrics import rendering_stats
|
| -from telemetry.page import page_measurement
|
| from telemetry.page.perf_tests_helper import FlattenList
|
| from telemetry.util import statistics
|
| -from telemetry.core.timeline.model import TimelineModel
|
| +from telemetry.core.timeline import bounds
|
|
|
| -TIMELINE_MARKER = 'Smoothness'
|
|
|
| -
|
| -class MissingDisplayFrameRateError(page_measurement.MeasurementFailure):
|
| - def __init__(self, name):
|
| - super(MissingDisplayFrameRateError, self).__init__(
|
| - 'Missing display frame rate metrics: ' + name)
|
| -
|
| -class NotEnoughFramesError(page_measurement.MeasurementFailure):
|
| - def __init__(self):
|
| - super(NotEnoughFramesError, self).__init__(
|
| - 'Page output less than two frames')
|
| -
|
| -
|
| -class NoSupportedActionError(page_measurement.MeasurementFailure):
|
| - def __init__(self):
|
| - super(NoSupportedActionError, self).__init__(
|
| - 'None of the actions is supported by smoothness measurement')
|
| -
|
| -
|
| -def _GetSyntheticDelayCategoriesFromPage(page):
|
| - if not hasattr(page, 'synthetic_delays'):
|
| - return []
|
| - result = []
|
| - for delay, options in page.synthetic_delays.items():
|
| - options = '%f;%s' % (options.get('target_duration', 0),
|
| - options.get('mode', 'static'))
|
| - result.append('DELAY(%s;%s)' % (delay, options))
|
| - return result
|
| -
|
| -
|
| -class SmoothnessMetric(Metric):
|
| +class SmoothnessMetric(timeline_based_metric.TimelineBasedMetric):
|
| def __init__(self):
|
| super(SmoothnessMetric, self).__init__()
|
| - self._stats = None
|
| - self._actions = []
|
| -
|
| - def AddActionToIncludeInMetric(self, action):
|
| - self._actions.append(action)
|
| -
|
| - def Start(self, page, tab):
|
| - custom_categories = ['webkit.console', 'benchmark']
|
| - custom_categories += _GetSyntheticDelayCategoriesFromPage(page)
|
| - tab.browser.StartTracing(','.join(custom_categories), 60)
|
| - tab.ExecuteJavaScript('console.time("' + TIMELINE_MARKER + '")')
|
| - if tab.browser.platform.IsRawDisplayFrameRateSupported():
|
| - tab.browser.platform.StartRawDisplayFrameRateMeasurement()
|
|
|
| - def Stop(self, page, tab):
|
| - if tab.browser.platform.IsRawDisplayFrameRateSupported():
|
| - tab.browser.platform.StopRawDisplayFrameRateMeasurement()
|
| - tab.ExecuteJavaScript('console.timeEnd("' + TIMELINE_MARKER + '")')
|
| - tracing_timeline_data = tab.browser.StopTracing()
|
| - timeline_model = TimelineModel(timeline_data=tracing_timeline_data)
|
| - timeline_ranges = [ action.GetActiveRangeOnTimeline(timeline_model)
|
| - for action in self._actions ]
|
| -
|
| - renderer_process = timeline_model.GetRendererProcessFromTab(tab)
|
| - self._stats = rendering_stats.RenderingStats(
|
| - renderer_process, timeline_model.browser_process, timeline_ranges)
|
| -
|
| - if not self._stats.frame_times:
|
| - raise NotEnoughFramesError()
|
| -
|
| - def AddResults(self, tab, results):
|
| - if self._stats.mouse_wheel_scroll_latency:
|
| + def AddResults(self, model, renderer_thread, interaction_record, results):
|
| + renderer_process = renderer_thread.parent
|
| + time_bounds = bounds.Bounds()
|
| + time_bounds.AddValue(interaction_record.start)
|
| + time_bounds.AddValue(interaction_record.end)
|
| + stats = rendering_stats.RenderingStats(
|
| + renderer_process, model.browser_process, [time_bounds])
|
| + if stats.mouse_wheel_scroll_latency:
|
| mean_mouse_wheel_scroll_latency = statistics.ArithmeticMean(
|
| - self._stats.mouse_wheel_scroll_latency)
|
| + stats.mouse_wheel_scroll_latency)
|
| mouse_wheel_scroll_latency_discrepancy = statistics.DurationsDiscrepancy(
|
| - self._stats.mouse_wheel_scroll_latency)
|
| + stats.mouse_wheel_scroll_latency)
|
| results.Add('mean_mouse_wheel_scroll_latency', 'ms',
|
| round(mean_mouse_wheel_scroll_latency, 3))
|
| results.Add('mouse_wheel_scroll_latency_discrepancy', '',
|
| round(mouse_wheel_scroll_latency_discrepancy, 4))
|
|
|
| - if self._stats.touch_scroll_latency:
|
| + if stats.touch_scroll_latency:
|
| mean_touch_scroll_latency = statistics.ArithmeticMean(
|
| - self._stats.touch_scroll_latency)
|
| + stats.touch_scroll_latency)
|
| touch_scroll_latency_discrepancy = statistics.DurationsDiscrepancy(
|
| - self._stats.touch_scroll_latency)
|
| + stats.touch_scroll_latency)
|
| results.Add('mean_touch_scroll_latency', 'ms',
|
| round(mean_touch_scroll_latency, 3))
|
| results.Add('touch_scroll_latency_discrepancy', '',
|
| round(touch_scroll_latency_discrepancy, 4))
|
|
|
| - if self._stats.js_touch_scroll_latency:
|
| + if stats.js_touch_scroll_latency:
|
| mean_js_touch_scroll_latency = statistics.ArithmeticMean(
|
| - self._stats.js_touch_scroll_latency)
|
| + stats.js_touch_scroll_latency)
|
| js_touch_scroll_latency_discrepancy = statistics.DurationsDiscrepancy(
|
| - self._stats.js_touch_scroll_latency)
|
| + stats.js_touch_scroll_latency)
|
| results.Add('mean_js_touch_scroll_latency', 'ms',
|
| round(mean_js_touch_scroll_latency, 3))
|
| results.Add('js_touch_scroll_latency_discrepancy', '',
|
| round(js_touch_scroll_latency_discrepancy, 4))
|
|
|
| # List of raw frame times.
|
| - frame_times = FlattenList(self._stats.frame_times)
|
| + frame_times = FlattenList(stats.frame_times)
|
| results.Add('frame_times', 'ms', frame_times)
|
|
|
| # Arithmetic mean of frame times.
|
| @@ -114,16 +60,10 @@ class SmoothnessMetric(Metric):
|
|
|
| # Absolute discrepancy of frame time stamps.
|
| frame_discrepancy = statistics.TimestampsDiscrepancy(
|
| - self._stats.frame_timestamps)
|
| + stats.frame_timestamps)
|
| results.Add('jank', 'ms', round(frame_discrepancy, 4))
|
|
|
| # Are we hitting 60 fps for 95 percent of all frames?
|
| # We use 19ms as a somewhat looser threshold, instead of 1000.0/60.0.
|
| percentile_95 = statistics.Percentile(frame_times, 95.0)
|
| results.Add('mostly_smooth', 'score', 1.0 if percentile_95 < 19.0 else 0.0)
|
| -
|
| - if tab.browser.platform.IsRawDisplayFrameRateSupported():
|
| - for r in tab.browser.platform.GetRawDisplayFrameRateMeasurements():
|
| - if r.value is None:
|
| - raise MissingDisplayFrameRateError(r.name)
|
| - results.Add(r.name, r.unit, r.value)
|
|
|