1 # Copyright (c) 2013 The Chromium OS 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 """This is a client side WebGL many planets deep test.""" 5 6 import numpy 7 import os 8 import time 9 10 from autotest_lib.client.bin import test 11 from autotest_lib.client.common_lib import error 12 from autotest_lib.client.bin import utils 13 from autotest_lib.client.common_lib.cros import chrome 14 from autotest_lib.client.cros.graphics import graphics_utils 15 16 17 class graphics_WebGLManyPlanetsDeep(test.test): 18 """WebGL many planets deep graphics test.""" 19 version = 1 20 GSC = None 21 frame_data = {} 22 perf_keyval = {} 23 test_duration_secs = 30 24 25 def setup(self): 26 self.job.setup_dep(['webgl_mpd']) 27 self.job.setup_dep(['graphics']) 28 29 def initialize(self): 30 self.GSC = graphics_utils.GraphicsStateChecker() 31 32 def cleanup(self): 33 if self.GSC: 34 keyvals = self.GSC.get_memory_keyvals() 35 for key, val in keyvals.iteritems(): 36 self.output_perf_value( 37 description=key, 38 value=val, 39 units='bytes', 40 higher_is_better=False) 41 self.GSC.finalize() 42 self.write_perf_keyval(keyvals) 43 44 def run_many_planets_deep_test(self, browser, test_url): 45 """Runs the many planets deep test from the given url. 46 47 @param browser: The Browser object to run the test with. 48 @param test_url: The URL to the many planets deep test site. 49 """ 50 if not utils.wait_for_idle_cpu(60.0, 0.1): 51 if not utils.wait_for_idle_cpu(20.0, 0.2): 52 raise error.TestFail('Failed: Could not get idle CPU.') 53 54 tab = browser.tabs.New() 55 tab.Navigate(test_url) 56 tab.Activate() 57 tab.WaitForDocumentReadyStateToBeComplete() 58 59 # Wait 3 seconds for the page to stabilize. 60 time.sleep(3) 61 62 # Reset our own FPS counter and start recording FPS and rendering time. 63 end_time = time.time() + self.test_duration_secs 64 tab.ExecuteJavaScript('g_crosFpsCounter.reset();') 65 while time.time() < end_time: 66 frame_data = tab.EvaluateJavaScript( 67 'g_crosFpsCounter.getFrameData();') 68 for datum in frame_data: 69 if not datum or datum['seq'] in self.frame_data: 70 continue 71 self.frame_data[datum['seq']] = { 72 'start_time': datum['startTime'], 73 'frame_elapsed_time': datum['frameElapsedTime'], 74 'js_elapsed_time': datum['jsElapsedTime'] 75 } 76 time.sleep(1) 77 tab.Close() 78 79 def calculate_perf_values(self): 80 """Calculates all the perf values from the collected data.""" 81 arr = numpy.array([[v['frame_elapsed_time'], v['js_elapsed_time']] 82 for v in self.frame_data.itervalues()]) 83 std = arr.std(axis=0) 84 mean = arr.mean(axis=0) 85 avg_fps = 1000.0 / mean[0] 86 self.perf_keyval.update({ 87 'average_fps': avg_fps, 88 'per_frame_dt_ms_std': std[0], 89 'per_frame_dt_ms_mean': mean[0], 90 'js_render_time_ms_std': std[1], 91 'js_render_time_ms_mean': mean[1] 92 }) 93 self.output_perf_value( 94 description='average_fps', 95 value=avg_fps, 96 units='fps', 97 higher_is_better=True) 98 99 with open('frame_data', 'w') as f: 100 line_format = '%10s %20s %20s %20s\n' 101 f.write(line_format % ('seq', 'start_time', 'frame_render_time_ms', 102 'js_render_time_ms')) 103 for k in sorted(self.frame_data.keys()): 104 d = self.frame_data[k] 105 f.write(line_format % (k, d['start_time'], 106 d['frame_elapsed_time'], 107 d['js_elapsed_time'])) 108 109 def run_once(self, test_duration_secs=30, fullscreen=True): 110 """Finds a brower with telemetry, and run the test. 111 112 @param test_duration_secs: The test duration in seconds to run the test 113 for. 114 @param fullscreen: Whether to run the test in fullscreen. 115 """ 116 self.test_duration_secs = test_duration_secs 117 118 ext_paths = [] 119 if fullscreen: 120 ext_paths.append( 121 os.path.join(self.autodir, 'deps', 'graphics', 122 'graphics_test_extension')) 123 124 with chrome.Chrome(logged_in=False, 125 extension_paths=ext_paths, 126 init_network_controller=True) as cr: 127 websrc_dir = os.path.join(self.autodir, 'deps', 'webgl_mpd', 'src') 128 if not cr.browser.platform.SetHTTPServerDirectories(websrc_dir): 129 raise error.TestFail('Failed: Unable to start HTTP server') 130 test_url = cr.browser.platform.http_server.UrlOf( 131 os.path.join(websrc_dir, 'ManyPlanetsDeep.html')) 132 self.run_many_planets_deep_test(cr.browser, test_url) 133 134 self.calculate_perf_values() 135 self.write_perf_keyval(self.perf_keyval) 136