diff options
author | ernstm@chromium.org <ernstm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-13 19:34:37 +0000 |
---|---|---|
committer | ernstm@chromium.org <ernstm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-13 19:34:37 +0000 |
commit | acc4ec81894936924635a483c3b6c146c30cde54 (patch) | |
tree | 0df719415807132d21c11d294479b4c9239392dd /tools | |
parent | b7568e1e711e6463bba8ae52bc793e0eb99b985d (diff) | |
download | chromium_src-acc4ec81894936924635a483c3b6c146c30cde54.zip chromium_src-acc4ec81894936924635a483c3b6c146c30cde54.tar.gz chromium_src-acc4ec81894936924635a483c3b6c146c30cde54.tar.bz2 |
telemetry: Add repaint benchmark.
R=nduca@chromium.org,tonyg@chromium.org
BUG=349102
Review URL: https://codereview.chromium.org/181243005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@256882 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/benchmarks/repaint.py | 35 | ||||
-rw-r--r-- | tools/perf/measurements/repaint.py | 57 | ||||
-rw-r--r-- | tools/perf/measurements/repaint_unittest.py | 44 | ||||
-rw-r--r-- | tools/perf/page_sets/key_mobile_sites.json | 1 | ||||
-rw-r--r-- | tools/perf/page_sets/top_25.json | 1 | ||||
-rw-r--r-- | tools/telemetry/telemetry/page/actions/repaint_continuously.py | 47 | ||||
-rw-r--r-- | tools/telemetry/telemetry/page/page_measurement_unittest_base.py | 1 |
7 files changed, 186 insertions, 0 deletions
diff --git a/tools/perf/benchmarks/repaint.py b/tools/perf/benchmarks/repaint.py new file mode 100644 index 0000000..ddb0d23 --- /dev/null +++ b/tools/perf/benchmarks/repaint.py @@ -0,0 +1,35 @@ +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +from measurements import repaint +from telemetry import test + + +class RepaintThreadedRasterizationKeyMobileSites(test.Test): + """Measures repaint performance on the key mobile sites with threaded + rasterization. + + http://www.chromium.org/developers/design-documents/rendering-benchmarks""" + tag = 'threaded_rasterization' + test = repaint.Repaint + page_set = 'page_sets/key_mobile_sites.json' + def CustomizeBrowserOptions(self, options): + options.AppendExtraBrowserArgs('--enable-threaded-compositing') + options.AppendExtraBrowserArgs('--force-compositing-mode') + options.AppendExtraBrowserArgs('--enable-impl-side-painting') + + +class RepaintGpuRasterizationKeyMobileSites(test.Test): + """Measures repaint performance on the key mobile sites with forced GPU + rasterization. + + http://www.chromium.org/developers/design-documents/rendering-benchmarks""" + tag = 'gpu_rasterization' + test = repaint.Repaint + page_set = 'page_sets/key_mobile_sites.json' + def CustomizeBrowserOptions(self, options): + options.AppendExtraBrowserArgs('--enable-threaded-compositing') + options.AppendExtraBrowserArgs('--force-compositing-mode') + options.AppendExtraBrowserArgs('--enable-impl-side-painting') + options.AppendExtraBrowserArgs('--force-gpu-rasterization') diff --git a/tools/perf/measurements/repaint.py b/tools/perf/measurements/repaint.py new file mode 100644 index 0000000..e7201e1 --- /dev/null +++ b/tools/perf/measurements/repaint.py @@ -0,0 +1,57 @@ +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +from metrics import smoothness +from metrics import timeline_interaction_record as tir_module +from telemetry.core.timeline.model import TimelineModel +from telemetry.page import page_measurement + +import telemetry.core.timeline.bounds as timeline_bounds + + +class Repaint(page_measurement.PageMeasurement): + def __init__(self): + super(Repaint, self).__init__('repaint', False) + self._smoothness_metric = None + self._timeline_model = None + self._actions = [] + + def CanRunForPage(self, page): + return hasattr(page, 'repaint') + + def WillRunActions(self, page, tab): + tab.WaitForDocumentReadyStateToBeComplete() + # Rasterize only what's visible. + tab.ExecuteJavaScript( + 'chrome.gpuBenchmarking.setRasterizeOnlyVisibleContent();') + self._smoothness_metric = smoothness.SmoothnessMetric() + # Start tracing for smoothness metric. + custom_categories = 'webkit.console,benchmark' + tab.browser.StartTracing(custom_categories, 60) + + def DidRunAction(self, page, tab, action): + self._actions.append(action) + + def DidRunActions(self, page, tab): + # Stop tracing for smoothness metric. + tracing_timeline_data = tab.browser.StopTracing() + self._timeline_model = TimelineModel(timeline_data=tracing_timeline_data) + + def MeasurePage(self, page, tab, results): + # Add results of smoothness metric. This computes the smoothness metric for + # the time range between the first action starts and the last action ends. + time_bounds = timeline_bounds.Bounds() + for action in self._actions: + time_bounds.AddBounds( + action.GetActiveRangeOnTimeline(self._timeline_model)) + # Create an interaction_record for this legacy measurement. Since we don't + # wrap the results that is sent to smoothnes metric, the logical_name will + # not be used. + interaction_record = tir_module.TimelineInteractionRecord( + 'smoothness_interaction', time_bounds.min, time_bounds.max) + renderer_thread = self._timeline_model.GetRendererThreadFromTab(tab) + self._smoothness_metric.AddResults(self._timeline_model, + renderer_thread, + interaction_record, + results) diff --git a/tools/perf/measurements/repaint_unittest.py b/tools/perf/measurements/repaint_unittest.py new file mode 100644 index 0000000..b79d896 --- /dev/null +++ b/tools/perf/measurements/repaint_unittest.py @@ -0,0 +1,44 @@ +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +from measurements import repaint +from telemetry.core import wpr_modes +from telemetry.page import page_measurement_unittest_base +from telemetry.unittest import options_for_unittests + + +class RepaintUnitTest( + page_measurement_unittest_base.PageMeasurementUnitTestBase): + """Smoke test for repaint measurement + + Runs repaint measurement on a simple page and verifies + that all metrics were added to the results. The test is purely functional, + i.e. it only checks if the metrics are present and non-zero. + """ + + def setUp(self): + self._options = options_for_unittests.GetCopy() + self._options.browser_options.wpr_mode = wpr_modes.WPR_OFF + + def testRepaint(self): + ps = self.CreatePageSetFromFileInUnittestDataDir('blank.html') + measurement = repaint.Repaint() + results = self.RunMeasurement(measurement, ps, options=self._options) + self.assertEquals(0, len(results.failures)) + + frame_times = results.FindAllPageSpecificValuesNamed('frame_times') + self.assertEquals(len(frame_times), 1) + self.assertGreater(frame_times[0].GetRepresentativeNumber(), 0) + + mean_frame_time = results.FindAllPageSpecificValuesNamed('mean_frame_time') + self.assertEquals(len(mean_frame_time), 1) + self.assertGreater(mean_frame_time[0].GetRepresentativeNumber(), 0) + + jank = results.FindAllPageSpecificValuesNamed('jank') + self.assertEquals(len(jank), 1) + self.assertGreater(jank[0].GetRepresentativeNumber(), 0) + + mostly_smooth = results.FindAllPageSpecificValuesNamed('mostly_smooth') + self.assertEquals(len(mostly_smooth), 1) + self.assertGreaterEqual(mostly_smooth[0].GetRepresentativeNumber(), 0) diff --git a/tools/perf/page_sets/key_mobile_sites.json b/tools/perf/page_sets/key_mobile_sites.json index 250aa59..8ef245d 100644 --- a/tools/perf/page_sets/key_mobile_sites.json +++ b/tools/perf/page_sets/key_mobile_sites.json @@ -4,6 +4,7 @@ "credentials_path": "data/credentials.json", "user_agent_type": "mobile", "smoothness": { "action": "scroll" }, + "repaint": { "action": "repaint_continuously", "seconds": 5 }, "pages": [ { "url": "http://www.androidpolice.com/2012/10/03/rumor-evidence-mounts-that-an-lg-optimus-g-nexus-is-coming-along-with-a-nexus-phone-certification-program/", diff --git a/tools/perf/page_sets/top_25.json b/tools/perf/page_sets/top_25.json index 09bb106..0155baa 100644 --- a/tools/perf/page_sets/top_25.json +++ b/tools/perf/page_sets/top_25.json @@ -4,6 +4,7 @@ "credentials_path": "data/credentials.json", "user_agent_type": "desktop", "smoothness": { "action": "scroll" }, + "repaint": { "action": "repaint_continuously", "seconds": 5 }, "pages": [ { "url": "https://www.google.com/#hl=en&q=barack+obama", diff --git a/tools/telemetry/telemetry/page/actions/repaint_continuously.py b/tools/telemetry/telemetry/page/actions/repaint_continuously.py new file mode 100644 index 0000000..c6578ab --- /dev/null +++ b/tools/telemetry/telemetry/page/actions/repaint_continuously.py @@ -0,0 +1,47 @@ +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import time + +from telemetry.page.actions import page_action + +class RepaintContinuouslyAction(page_action.PageAction): + """ Continuously repaints the visible content by requesting animation frames + until self.seconds have elapsed AND at least three RAFs have been fired. Times + out after max(60, self.seconds), if less than three RAFs were fired. + """ + def __init__(self, attributes=None): + super(RepaintContinuouslyAction, self).__init__(attributes) + self._SetTimelineMarkerBaseName('RepaintContinuouslyAction::RunAction') + + def RunAction(self, page, tab): + assert(hasattr(self, 'seconds')) + tab.ExecuteJavaScript( + 'console.time("' + self._GetUniqueTimelineMarkerName() + '")') + start_time = time.time() + tab.ExecuteJavaScript( + 'window.__rafCount = 0;' + 'window.__rafFunction = function() {' + 'window.__rafCount += 1;' + 'chrome.gpuBenchmarking.setNeedsDisplayOnAllLayers();' + 'window.webkitRequestAnimationFrame(window.__rafFunction);' + '};' + 'window.webkitRequestAnimationFrame(window.__rafFunction);') + + time_out = max(60, self.seconds) + min_rafs = 3 + + # Wait until al leat self.seconds have elapsed AND min_rafs have been fired. + # Use a hard time-out after 60 seconds (or self.seconds). + while True: + raf_count = tab.EvaluateJavaScript('window.__rafCount;') + elapsed_time = time.time() - start_time + if elapsed_time > time_out: + break + elif elapsed_time > self.seconds and raf_count > min_rafs: + break + time.sleep(1) + + tab.ExecuteJavaScript( + 'console.timeEnd("' + self._GetUniqueTimelineMarkerName() + '")') diff --git a/tools/telemetry/telemetry/page/page_measurement_unittest_base.py b/tools/telemetry/telemetry/page/page_measurement_unittest_base.py index 65d97f5..4a02279 100644 --- a/tools/telemetry/telemetry/page/page_measurement_unittest_base.py +++ b/tools/telemetry/telemetry/page/page_measurement_unittest_base.py @@ -23,6 +23,7 @@ class PageMeasurementUnitTestBase(unittest.TestCase): ps = page_set.PageSet(file_path=base_dir) page = page_module.Page(test_filename, ps, base_dir=base_dir) setattr(page, 'smoothness', {'action': 'scroll'}) + setattr(page, 'repaint', { "action": "repaint_continuously", "seconds": 2 }) ps.pages.append(page) return ps |