1ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang# Use of this source code is governed by a BSD-style license that can be
3ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang# found in the LICENSE file.
4639eddc6bf8bb76d102a3fc42833f806e177c3ecRicky Liang
5639eddc6bf8bb76d102a3fc42833f806e177c3ecRicky Liang"""This is a client side WebGL aquarium test.
6639eddc6bf8bb76d102a3fc42833f806e177c3ecRicky Liang
7639eddc6bf8bb76d102a3fc42833f806e177c3ecRicky LiangDescription of some of the test result output:
8639eddc6bf8bb76d102a3fc42833f806e177c3ecRicky Liang    - interframe time: The time elapsed between two frames. It is the elapsed
9639eddc6bf8bb76d102a3fc42833f806e177c3ecRicky Liang            time between two consecutive calls to the render() function.
10639eddc6bf8bb76d102a3fc42833f806e177c3ecRicky Liang    - render time: The time it takes in Javascript to construct a frame and
11639eddc6bf8bb76d102a3fc42833f806e177c3ecRicky Liang            submit all the GL commands. It is the time it takes for a render()
12639eddc6bf8bb76d102a3fc42833f806e177c3ecRicky Liang            function call to complete.
13639eddc6bf8bb76d102a3fc42833f806e177c3ecRicky Liang"""
14ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
15ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liangimport logging
16ff9c82b221cbc0cc9d4951fc609479d826067d33Salva Climentimport math
17ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liangimport os
18ff9c82b221cbc0cc9d4951fc609479d826067d33Salva Climentimport sampler
19ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liangimport threading
20ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liangimport time
21ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
22ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liangfrom autotest_lib.client.bin import test, utils
23ff9c82b221cbc0cc9d4951fc609479d826067d33Salva Climentfrom autotest_lib.client.common_lib import error
24ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liangfrom autotest_lib.client.common_lib.cros import chrome
2567eac4d97a9e69f3fbe52c78b4d7f7fa35cfe562Ilja H. Friedelfrom autotest_lib.client.cros.graphics import graphics_utils
26e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasanafrom autotest_lib.client.cros import power_status, power_utils
27e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasanafrom autotest_lib.client.cros import service_stopper
28e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
29e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana# Minimum battery charge percentage to run the test
30e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit MakasanaBATTERY_INITIAL_CHARGED_MIN = 10
31e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
32e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana# Measurement duration in seconds.
33e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit MakasanaMEASUREMENT_DURATION = 30
34e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
35e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit MakasanaPOWER_DESCRIPTION = 'avg_energy_rate_1000_fishes'
36e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
37e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana# Time to exclude from calculation after playing a webgl demo [seconds].
38e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit MakasanaSTABILIZATION_DURATION = 10
39ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
40ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
41b6aed51feee1d07fa2465fa3b2fe53cd3f247defPo-Hsien Wangclass graphics_WebGLAquarium(graphics_utils.GraphicsTest):
42ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang    """WebGL aquarium graphics test."""
43ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang    version = 1
44a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel
45a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel    _backlight = None
46a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel    _power_status = None
47a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel    _service_stopper = None
48a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel    _test_power = False
49a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel    active_tab = None
50a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel    flip_stats = {}
51a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel    kernel_sampler = None
52a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel    perf_keyval = {}
53a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel    sampler_lock = None
54a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel    test_duration_secs = 30
55a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel    test_setting_num_fishes = 50
56619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel    test_settings = {
57619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel        50: ('setSetting2', 2),
58619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel        1000: ('setSetting6', 6),
59619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel    }
60ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
61ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang    def setup(self):
62ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        tarball_path = os.path.join(self.bindir,
63ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                                    'webgl_aquarium_static.tar.bz2')
64ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        utils.extract_tarball_to_dir(tarball_path, self.srcdir)
65ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
66ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang    def initialize(self):
67b6aed51feee1d07fa2465fa3b2fe53cd3f247defPo-Hsien Wang        super(graphics_WebGLAquarium, self).initialize()
68ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        self.sampler_lock = threading.Lock()
69a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel        # TODO: Create samplers for other platforms (e.g. x86).
70ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        if utils.get_board().lower() in ['daisy', 'daisy_spring']:
71ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            # Enable ExynosSampler on Exynos platforms.  The sampler looks for
72ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            # exynos-drm page flip states: 'wait_kds', 'rendered', 'prepared',
73ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            # and 'flipped' in kernel debugfs.
74ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
75ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            # Sample 3-second durtaion for every 5 seconds.
76ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            self.kernel_sampler = sampler.ExynosSampler(period=5, duration=3)
77ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            self.kernel_sampler.sampler_callback = self.exynos_sampler_callback
78ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            self.kernel_sampler.output_flip_stats = (
79619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                self.exynos_output_flip_stats)
80ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
8167eac4d97a9e69f3fbe52c78b4d7f7fa35cfe562Ilja H. Friedel    def cleanup(self):
82e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        if self._backlight:
83e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            self._backlight.restore()
84d13b4f4ca7223700c649413393506a89d6c3cfcdRohit Makasana        if self._service_stopper:
85d13b4f4ca7223700c649413393506a89d6c3cfcdRohit Makasana            self._service_stopper.restore_services()
860b1d88ba975bf1dd60a41a9ef0e9c9dd40d41841Po-Hsien Wang
87b6aed51feee1d07fa2465fa3b2fe53cd3f247defPo-Hsien Wang        if self._GSC:
88b6aed51feee1d07fa2465fa3b2fe53cd3f247defPo-Hsien Wang            keyvals = self._GSC.get_memory_difference_keyvals()
89e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            if not self._test_power:
90e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                for key, val in keyvals.iteritems():
91619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                    self.output_perf_value(
92619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                        description=key,
93619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                        value=val,
94619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                        units='bytes',
95619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                        higher_is_better=False)
9667eac4d97a9e69f3fbe52c78b4d7f7fa35cfe562Ilja H. Friedel            self.write_perf_keyval(keyvals)
97b6aed51feee1d07fa2465fa3b2fe53cd3f247defPo-Hsien Wang        super(graphics_WebGLAquarium, self).cleanup()
9867eac4d97a9e69f3fbe52c78b4d7f7fa35cfe562Ilja H. Friedel
99e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana    def run_fish_test(self, browser, test_url, num_fishes, perf_log=True):
100ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        """Run the test with the given number of fishes.
101ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
102ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        @param browser: The Browser object to run the test with.
103ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        @param test_url: The URL to the aquarium test site.
104ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        @param num_fishes: The number of fishes to run the test with.
105e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        @param perf_log: Report perf data only if it's set to True.
106ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        """
107ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        # Create tab and load page. Set the number of fishes when page is fully
108ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        # loaded.
109ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        tab = browser.tabs.New()
110ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        tab.Navigate(test_url)
111ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        tab.Activate()
112ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        self.active_tab = tab
113b55c3a375c3584cb18c0c8249aab8095b7eb23eeIlja H. Friedel        tab.WaitForDocumentReadyStateToBeComplete()
114ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
115ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        # Set the number of fishes when document finishes loading.  Also reset
116ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        # our own FPS counter and start recording FPS and rendering time.
117a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel        utils.wait_for_value(
1180b1d88ba975bf1dd60a41a9ef0e9c9dd40d41841Po-Hsien Wang            lambda: tab.EvaluateJavaScript(
1190b1d88ba975bf1dd60a41a9ef0e9c9dd40d41841Po-Hsien Wang                'if (document.readyState === "complete") {'
1200b1d88ba975bf1dd60a41a9ef0e9c9dd40d41841Po-Hsien Wang                '  setSetting(document.getElementById("%s"), %d);'
1210b1d88ba975bf1dd60a41a9ef0e9c9dd40d41841Po-Hsien Wang                '  g_crosFpsCounter.reset();'
1220b1d88ba975bf1dd60a41a9ef0e9c9dd40d41841Po-Hsien Wang                '  true;'
1230b1d88ba975bf1dd60a41a9ef0e9c9dd40d41841Po-Hsien Wang                '} else {'
1240b1d88ba975bf1dd60a41a9ef0e9c9dd40d41841Po-Hsien Wang                '  false;'
1250b1d88ba975bf1dd60a41a9ef0e9c9dd40d41841Po-Hsien Wang                '}' % self.test_settings[num_fishes]
1260b1d88ba975bf1dd60a41a9ef0e9c9dd40d41841Po-Hsien Wang            ),
127619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel            expected_value=True,
128619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel            timeout_sec=30)
129ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
130ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        if self.kernel_sampler:
131ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            self.kernel_sampler.start_sampling_thread()
132ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        time.sleep(self.test_duration_secs)
133ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        if self.kernel_sampler:
134ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            self.kernel_sampler.stop_sampling_thread()
135a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel            self.kernel_sampler.output_flip_stats('flip_stats_%d' % num_fishes)
136ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            self.flip_stats = {}
137ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
13823c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch        # Get average FPS and rendering time, then close the tab.
13923c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch        avg_fps = tab.EvaluateJavaScript('g_crosFpsCounter.getAvgFps();')
14023c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch        if math.isnan(float(avg_fps)):
141619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel            raise error.TestFail('Failed: Could not get FPS count.')
14223c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch
14323c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch        avg_interframe_time = tab.EvaluateJavaScript(
144619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel            'g_crosFpsCounter.getAvgInterFrameTime();')
14523c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch        avg_render_time = tab.EvaluateJavaScript(
146619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel            'g_crosFpsCounter.getAvgRenderTime();')
14723c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch        std_interframe_time = tab.EvaluateJavaScript(
148619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel            'g_crosFpsCounter.getStdInterFrameTime();')
14923c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch        std_render_time = tab.EvaluateJavaScript(
150619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel            'g_crosFpsCounter.getStdRenderTime();')
15123c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch        self.perf_keyval['avg_fps_%04d_fishes' % num_fishes] = avg_fps
15223c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch        self.perf_keyval['avg_interframe_time_%04d_fishes' % num_fishes] = (
153619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel            avg_interframe_time)
15423c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch        self.perf_keyval['avg_render_time_%04d_fishes' % num_fishes] = (
155619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel            avg_render_time)
15623c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch        self.perf_keyval['std_interframe_time_%04d_fishes' % num_fishes] = (
157619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel            std_interframe_time)
15823c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch        self.perf_keyval['std_render_time_%04d_fishes' % num_fishes] = (
159619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel            std_render_time)
16023c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch        logging.info('%d fish(es): Average FPS = %f, '
16123c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch                     'average render time = %f', num_fishes, avg_fps,
16223c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch                     avg_render_time)
163e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        if perf_log:
164a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel            self.output_perf_value(
165619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                description='avg_fps_%04d_fishes' % num_fishes,
166619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                value=avg_fps,
167619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                units='fps',
168619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                higher_is_better=True)
169e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
17023c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch    def run_power_test(self, browser, test_url, ac_ok):
171a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel        """Runs the webgl power consumption test and reports the perf results.
172e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
173e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        @param browser: The Browser object to run the test with.
174e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        @param test_url: The URL to the aquarium test site.
17523c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch        @param ac_ok: Boolean on whether its ok to have AC power supplied.
176e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        """
177e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
178e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        self._backlight = power_utils.Backlight()
179e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        self._backlight.set_default()
180e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
181e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        self._service_stopper = service_stopper.ServiceStopper(
182619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel            service_stopper.ServiceStopper.POWER_DRAW_SERVICES)
183e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        self._service_stopper.stop_services()
184e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
18523c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch        if not ac_ok:
18623c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch            self._power_status = power_status.get_status()
18723c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch            # Verify that we are running on battery and the battery is
18823c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch            # sufficiently charged.
18923c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch            self._power_status.assert_battery_state(BATTERY_INITIAL_CHARGED_MIN)
190e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
19123c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch            measurements = [
19223c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch                power_status.SystemPower(self._power_status.battery_path)
19323c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch            ]
194e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
195e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        def get_power():
196e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            power_logger = power_status.PowerLogger(measurements)
197e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            power_logger.start()
198e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            time.sleep(STABILIZATION_DURATION)
199e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            start_time = time.time()
200e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            time.sleep(MEASUREMENT_DURATION)
201e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            power_logger.checkpoint('result', start_time)
202e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            keyval = power_logger.calc()
203e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            logging.info('Power output %s', keyval)
204e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            return keyval['result_' + measurements[0].domain + '_pwr']
205e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
206e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        self.run_fish_test(browser, test_url, 1000, perf_log=False)
20723c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch        if not ac_ok:
20823c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch            energy_rate = get_power()
20923c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch            # This is a power specific test so we are not capturing
21023c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch            # avg_fps and avg_render_time in this test.
21123c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch            self.perf_keyval[POWER_DESCRIPTION] = energy_rate
212619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel            self.output_perf_value(
213619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                description=POWER_DESCRIPTION,
214619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                value=energy_rate,
215619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                units='W',
216619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                higher_is_better=False)
217e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
218ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang    def exynos_sampler_callback(self, sampler_obj):
219ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        """Sampler callback function for ExynosSampler.
220ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
221ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        @param sampler_obj: The ExynosSampler object that invokes this callback
222ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                function.
223ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        """
224ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        if sampler_obj.stopped:
225ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            return
226ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
227ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        with self.sampler_lock:
228ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            now = time.time()
229ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            results = {}
230ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            info_str = ['\nfb_id wait_kds flipped']
231ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            for value in sampler_obj.frame_buffers.itervalues():
232ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                results[value.fb] = {}
233ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                for state, stats in value.states.iteritems():
234ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                    results[value.fb][state] = (stats.avg, stats.stdev)
235619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                info_str.append('%s: %s %s' % (value.fb,
236619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                                               results[value.fb]['wait_kds'][0],
237619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                                               results[value.fb]['flipped'][0]))
238ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            results['avg_fps'] = self.active_tab.EvaluateJavaScript(
239619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                'g_crosFpsCounter.getAvgFps();')
240ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            results['avg_render_time'] = self.active_tab.EvaluateJavaScript(
241619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                'g_crosFpsCounter.getAvgRenderTime();')
242ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            self.active_tab.ExecuteJavaScript('g_crosFpsCounter.reset();')
243ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            info_str.append('avg_fps: %s, avg_render_time: %s' %
244ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                            (results['avg_fps'], results['avg_render_time']))
245ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            self.flip_stats[now] = results
246ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            logging.info('\n'.join(info_str))
247ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
248ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang    def exynos_output_flip_stats(self, file_name):
249ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        """Pageflip statistics output function for ExynosSampler.
250ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
251ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        @param file_name: The output file name.
252ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        """
253ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        # output format:
254ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        # time fb_id avg_rendered avg_prepared avg_wait_kds avg_flipped
255ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        # std_rendered std_prepared std_wait_kds std_flipped
256ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        with open(file_name, 'w') as f:
257ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            for t in sorted(self.flip_stats.keys()):
258ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                if ('avg_fps' in self.flip_stats[t] and
259619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                        'avg_render_time' in self.flip_stats[t]):
260a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel                    f.write('%s %s %s\n' %
261a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel                            (t, self.flip_stats[t]['avg_fps'],
262a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel                             self.flip_stats[t]['avg_render_time']))
263ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                for fb, stats in self.flip_stats[t].iteritems():
264ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                    if not isinstance(fb, int):
265ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                        continue
266ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                    f.write('%s %s ' % (t, fb))
267ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                    f.write('%s %s %s %s ' % (stats['rendered'][0],
268ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                                              stats['prepared'][0],
269ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                                              stats['wait_kds'][0],
270ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                                              stats['flipped'][0]))
271ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                    f.write('%s %s %s %s\n' % (stats['rendered'][1],
272ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                                               stats['prepared'][1],
273ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                                               stats['wait_kds'][1],
274ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                                               stats['flipped'][1]))
275619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel
276b6aed51feee1d07fa2465fa3b2fe53cd3f247defPo-Hsien Wang    @graphics_utils.GraphicsTest.failure_report_decorator('graphics_WebGLAquarium')
277a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel    def run_once(self,
278a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel                 test_duration_secs=30,
279a004701bd4ea9c695fbc4e5d9896061e0811512aIlja H. Friedel                 test_setting_num_fishes=(50, 1000),
280619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                 power_test=False,
281619ee2569463359d155539539f5c0d7b2515ccd6Ilja H. Friedel                 ac_ok=False):
2820b1d88ba975bf1dd60a41a9ef0e9c9dd40d41841Po-Hsien Wang        """Find a browser with telemetry, and run the test.
283ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
284ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        @param test_duration_secs: The duration in seconds to run each scenario
285ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                for.
286ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        @param test_setting_num_fishes: A list of the numbers of fishes to
287ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                enable in the test.
28823c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch        @param power_test: Boolean on whether to run power_test
28923c7247fa5d1f7b59fb4c17303699c3f513191a8Todd Broch        @param ac_ok: Boolean on whether its ok to have AC power supplied.
290ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        """
291ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        self.test_duration_secs = test_duration_secs
292ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        self.test_setting_num_fishes = test_setting_num_fishes
293ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
294bd762fd7ab3497f4690d381db9624525f6d953c5Achuith Bhandarkar        with chrome.Chrome(logged_in=False, init_network_controller=True) as cr:
2952bfa5640825faf707213abd2bee03f684547a938Ricky Liang            cr.browser.platform.SetHTTPServerDirectories(self.srcdir)
2962bfa5640825faf707213abd2bee03f684547a938Ricky Liang            test_url = cr.browser.platform.http_server.UrlOf(
2972bfa5640825faf707213abd2bee03f684547a938Ricky Liang                os.path.join(self.srcdir, 'aquarium.html'))
2982bfa5640825faf707213abd2bee03f684547a938Ricky Liang
2992bfa5640825faf707213abd2bee03f684547a938Ricky Liang            if not utils.wait_for_idle_cpu(60.0, 0.1):
3002bfa5640825faf707213abd2bee03f684547a938Ricky Liang                if not utils.wait_for_idle_cpu(20.0, 0.2):
3012bfa5640825faf707213abd2bee03f684547a938Ricky Liang                    raise error.TestFail('Failed: Could not get idle CPU.')
3022bfa5640825faf707213abd2bee03f684547a938Ricky Liang            if not utils.wait_for_cool_machine():
3032bfa5640825faf707213abd2bee03f684547a938Ricky Liang                raise error.TestFail('Failed: Could not get cold machine.')
3042bfa5640825faf707213abd2bee03f684547a938Ricky Liang            if power_test:
3052bfa5640825faf707213abd2bee03f684547a938Ricky Liang                self._test_power = True
3062bfa5640825faf707213abd2bee03f684547a938Ricky Liang                self.run_power_test(cr.browser, test_url, ac_ok)
3072bfa5640825faf707213abd2bee03f684547a938Ricky Liang                with self.sampler_lock:
3082bfa5640825faf707213abd2bee03f684547a938Ricky Liang                    self.active_tab.Close()
3092bfa5640825faf707213abd2bee03f684547a938Ricky Liang                    self.active_tab = None
3102bfa5640825faf707213abd2bee03f684547a938Ricky Liang            else:
3112bfa5640825faf707213abd2bee03f684547a938Ricky Liang                for n in self.test_setting_num_fishes:
3122bfa5640825faf707213abd2bee03f684547a938Ricky Liang                    self.run_fish_test(cr.browser, test_url, n)
3132bfa5640825faf707213abd2bee03f684547a938Ricky Liang                    # Do not close the tab when the sampler_callback is
3142bfa5640825faf707213abd2bee03f684547a938Ricky Liang                    # doing his work.
315e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                    with self.sampler_lock:
316e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                        self.active_tab.Close()
317e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                        self.active_tab = None
318ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        self.write_perf_keyval(self.perf_keyval)
319