1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)# found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import sys
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import time
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)from telemetry.core.util import TimeoutException
94ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdochfrom telemetry.page import page_test
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdochfrom telemetry.value import scalar
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class RasterizeAndRecordMicro(page_test.PageTest):
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  def __init__(self):
1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    super(RasterizeAndRecordMicro, self).__init__('')
16c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    self._chrome_branch_number = None
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  @classmethod
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  def AddCommandLineArgs(cls, parser):
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    parser.add_option('--start-wait-time', type='float',
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      default=2,
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      help='Wait time before the benchmark is started '
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      '(must be long enought to load all content)')
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    parser.add_option('--rasterize-repeat', type='int',
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      default=100,
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      help='Repeat each raster this many times. Increase '
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      'this value to reduce variance.')
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    parser.add_option('--record-repeat', type='int',
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      default=100,
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      help='Repeat each record this many times. Increase '
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      'this value to reduce variance.')
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    parser.add_option('--timeout', type='int',
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      default=120,
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      help='The length of time to wait for the micro '
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      'benchmark to finish, expressed in seconds.')
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    parser.add_option('--report-detailed-results',
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      action='store_true',
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      help='Whether to report additional detailed results.')
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  def CustomizeBrowserOptions(self, options):
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    options.AppendExtraBrowserArgs([
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        '--enable-impl-side-painting',
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        '--enable-threaded-compositing',
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        '--enable-gpu-benchmarking'
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ])
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  def DidStartBrowser(self, browser):
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    # TODO(vmpstr): Remove this temporary workaround when reference build has
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    # been updated to branch 1713 or later.
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    backend = browser._browser_backend # pylint: disable=W0212
51c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    self._chrome_branch_number = getattr(backend, 'chrome_branch_number', None)
52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (not self._chrome_branch_number or
53c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        (sys.platform != 'android' and self._chrome_branch_number < 1713)):
544ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch      raise page_test.TestNotSupportedOnPlatformFailure(
554ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch          'rasterize_and_record_micro requires Chrome branch 1713 '
564ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch          'or later. Skipping measurement.')
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  def ValidateAndMeasurePage(self, page, tab, results):
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    try:
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      tab.WaitForDocumentReadyStateToBeComplete()
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    except TimeoutException:
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      pass
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    time.sleep(self.options.start_wait_time)
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    record_repeat = self.options.record_repeat
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    rasterize_repeat = self.options.rasterize_repeat
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    # Enqueue benchmark
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    tab.ExecuteJavaScript("""
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window.benchmark_results = {};
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window.benchmark_results.done = false;
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        window.benchmark_results.id =
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            chrome.gpuBenchmarking.runMicroBenchmark(
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                "rasterize_and_record_benchmark",
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                function(value) {
75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                  window.benchmark_results.done = true;
76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                  window.benchmark_results.results = value;
77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                }, {
78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                  "record_repeat_count": """ + str(record_repeat) + """,
79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                  "rasterize_repeat_count": """ + str(rasterize_repeat) + """
80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                });
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    """)
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    benchmark_id = tab.EvaluateJavaScript('window.benchmark_results.id')
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (not benchmark_id):
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      raise page_test.MeasurementFailure(
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          'Failed to schedule rasterize_and_record_micro')
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    tab.WaitForJavaScriptExpression(
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        'window.benchmark_results.done', self.options.timeout)
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    data = tab.EvaluateJavaScript('window.benchmark_results.results')
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    pixels_recorded = data['pixels_recorded']
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    record_time = data['record_time_ms']
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    pixels_rasterized = data['pixels_rasterized']
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    rasterize_time = data['rasterize_time_ms']
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    results.AddValue(scalar.ScalarValue(
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        results.current_page, 'pixels_recorded', 'pixels', pixels_recorded))
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    results.AddValue(scalar.ScalarValue(
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        results.current_page, 'record_time', 'ms', record_time))
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    results.AddValue(scalar.ScalarValue(
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        results.current_page, 'pixels_rasterized', 'pixels', pixels_rasterized))
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    results.AddValue(scalar.ScalarValue(
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        results.current_page, 'rasterize_time', 'ms', rasterize_time))
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
107c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    # TODO(skyostil): Remove this temporary workaround when reference build has
108c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    # been updated to branch 1931 or later.
109c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if ((self._chrome_branch_number and self._chrome_branch_number >= 1931) or
110c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        sys.platform == 'android'):
111c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      record_time_sk_null_canvas = data['record_time_sk_null_canvas_ms']
112c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      record_time_painting_disabled = data['record_time_painting_disabled_ms']
1135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      record_time_skrecord = data['record_time_skrecord_ms']
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      results.AddValue(scalar.ScalarValue(
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          results.current_page, 'record_time_sk_null_canvas', 'ms',
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          record_time_sk_null_canvas))
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      results.AddValue(scalar.ScalarValue(
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          results.current_page, 'record_time_painting_disabled', 'ms',
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          record_time_painting_disabled))
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      results.AddValue(scalar.ScalarValue(
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          results.current_page, 'record_time_skrecord', 'ms',
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          record_time_skrecord))
123c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if self.options.report_detailed_results:
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      pixels_rasterized_with_non_solid_color = \
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          data['pixels_rasterized_with_non_solid_color']
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      pixels_rasterized_as_opaque = \
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          data['pixels_rasterized_as_opaque']
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      total_layers = data['total_layers']
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      total_picture_layers = data['total_picture_layers']
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      total_picture_layers_with_no_content = \
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          data['total_picture_layers_with_no_content']
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      total_picture_layers_off_screen = \
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          data['total_picture_layers_off_screen']
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      results.AddValue(scalar.ScalarValue(
137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          results.current_page, 'pixels_rasterized_with_non_solid_color',
138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          'pixels', pixels_rasterized_with_non_solid_color))
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      results.AddValue(scalar.ScalarValue(
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          results.current_page, 'pixels_rasterized_as_opaque', 'pixels',
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          pixels_rasterized_as_opaque))
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      results.AddValue(scalar.ScalarValue(
143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          results.current_page, 'total_layers', 'count', total_layers))
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      results.AddValue(scalar.ScalarValue(
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          results.current_page, 'total_picture_layers', 'count',
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          total_picture_layers))
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      results.AddValue(scalar.ScalarValue(
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          results.current_page, 'total_picture_layers_with_no_content', 'count',
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          total_picture_layers_with_no_content))
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      results.AddValue(scalar.ScalarValue(
151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          results.current_page, 'total_picture_layers_off_screen', 'count',
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          total_picture_layers_off_screen))
153