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