summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorernstm@chromium.org <ernstm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-13 19:34:37 +0000
committerernstm@chromium.org <ernstm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-13 19:34:37 +0000
commitacc4ec81894936924635a483c3b6c146c30cde54 (patch)
tree0df719415807132d21c11d294479b4c9239392dd /tools
parentb7568e1e711e6463bba8ae52bc793e0eb99b985d (diff)
downloadchromium_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.py35
-rw-r--r--tools/perf/measurements/repaint.py57
-rw-r--r--tools/perf/measurements/repaint_unittest.py44
-rw-r--r--tools/perf/page_sets/key_mobile_sites.json1
-rw-r--r--tools/perf/page_sets/top_25.json1
-rw-r--r--tools/telemetry/telemetry/page/actions/repaint_continuously.py47
-rw-r--r--tools/telemetry/telemetry/page/page_measurement_unittest_base.py1
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