1 # Copyright 2012 The Chromium Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 5 from metrics import power 6 7 from telemetry.core.platform import tracing_category_filter 8 from telemetry.core.platform import tracing_options 9 from telemetry.page import page_test 10 from telemetry.timeline import model 11 from telemetry.value import scalar 12 13 14 class ImageDecoding(page_test.PageTest): 15 def __init__(self): 16 super(ImageDecoding, self).__init__() 17 self._power_metric = None 18 19 def CustomizeBrowserOptions(self, options): 20 options.AppendExtraBrowserArgs('--enable-gpu-benchmarking') 21 power.PowerMetric.CustomizeBrowserOptions(options) 22 23 def WillStartBrowser(self, platform): 24 self._power_metric = power.PowerMetric(platform) 25 26 def WillNavigateToPage(self, page, tab): 27 tab.ExecuteJavaScript(""" 28 if (window.chrome && 29 chrome.gpuBenchmarking && 30 chrome.gpuBenchmarking.clearImageCache) { 31 chrome.gpuBenchmarking.clearImageCache(); 32 } 33 """) 34 self._power_metric.Start(page, tab) 35 36 options = tracing_options.TracingOptions() 37 options.enable_chrome_trace = True 38 # FIXME: Remove the timeline category when impl-side painting is on 39 # everywhere. 40 category_filter = tracing_category_filter.TracingCategoryFilter( 41 'disabled-by-default-devtools.timeline') 42 43 # FIXME: Remove webkit.console when blink.console lands in chromium and 44 # the ref builds are updated. crbug.com/386847 45 # FIXME: Remove the devtools.timeline category when impl-side painting is 46 # on everywhere. 47 categories = [ 48 'blink', 49 'devtools.timeline', 50 'webkit.console', 51 'blink.console' 52 ] 53 for c in categories: 54 category_filter.AddIncludedCategory(c) 55 tab.browser.platform.tracing_controller.Start(options, category_filter) 56 57 def StopBrowserAfterPage(self, browser, page): 58 return not browser.tabs[0].ExecuteJavaScript(""" 59 window.chrome && 60 chrome.gpuBenchmarking && 61 chrome.gpuBenchmarking.clearImageCache; 62 """) 63 64 def ValidateAndMeasurePage(self, page, tab, results): 65 timeline_data = tab.browser.platform.tracing_controller.Stop() 66 timeline_model = model.TimelineModel(timeline_data) 67 self._power_metric.Stop(page, tab) 68 self._power_metric.AddResults(tab, results) 69 70 def _IsDone(): 71 return tab.EvaluateJavaScript('isDone') 72 73 decode_image_events = timeline_model.GetAllEventsOfName( 74 'ImageFrameGenerator::decode') 75 # FIXME: Remove this when impl-side painting is on everywhere. 76 if not decode_image_events: 77 decode_image_events = timeline_model.GetAllEventsOfName('Decode Image') 78 79 # If it is a real image page, then store only the last-minIterations 80 # decode tasks. 81 if (hasattr(page, 82 'image_decoding_measurement_limit_results_to_min_iterations') and 83 page.image_decoding_measurement_limit_results_to_min_iterations): 84 assert _IsDone() 85 min_iterations = tab.EvaluateJavaScript('minIterations') 86 decode_image_events = decode_image_events[-min_iterations:] 87 88 durations = [d.duration for d in decode_image_events] 89 assert durations, 'Failed to find image decode trace events.' 90 91 image_decoding_avg = sum(durations) / len(durations) 92 results.AddValue(scalar.ScalarValue( 93 results.current_page, 'ImageDecoding_avg', 'ms', image_decoding_avg, 94 description='Average decode time for images in 4 different ' 95 'formats: gif, png, jpg, and webp. The image files are ' 96 'located at chrome/test/data/image_decoding.')) 97 results.AddValue(scalar.ScalarValue( 98 results.current_page, 'ImageLoading_avg', 'ms', 99 tab.EvaluateJavaScript('averageLoadingTimeMs()'))) 100 101 def CleanUpAfterPage(self, page, tab): 102 tracing_controller = tab.browser.platform.tracing_controller 103 if tracing_controller.is_tracing_running: 104 tracing_controller.Stop() 105