Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / content / public / android / javatests / src / org / chromium / content / browser / VSyncMonitorTest.java
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 package org.chromium.content.browser;
6
7 import android.content.Context;
8 import android.os.SystemClock;
9 import android.test.InstrumentationTestCase;
10 import android.test.suitebuilder.annotation.MediumTest;
11
12 import org.chromium.base.ThreadUtils;
13
14 import java.util.Arrays;
15 import java.util.concurrent.Callable;
16
17 public class VSyncMonitorTest extends InstrumentationTestCase {
18     private static class VSyncDataCollector implements VSyncMonitor.Listener {
19         public long mFramePeriods[];
20         public int mFrameCount;
21         public long mLastVSyncCpuTimeMillis;
22
23         private final boolean mActivelyRequestUpdate;
24         private boolean mDone;
25         private long mPreviousVSyncTimeMicros;
26         private Object mSyncRoot = new Object();
27
28         VSyncDataCollector(int frames, boolean activelyRequestUpdate) {
29             mFramePeriods = new long[frames];
30             mActivelyRequestUpdate = activelyRequestUpdate;
31         }
32
33         public boolean isDone() {
34             synchronized (mSyncRoot) {
35                 return mDone;
36             }
37         }
38
39         @Override
40         public void onVSync(VSyncMonitor monitor, long vsyncTimeMicros) {
41             mLastVSyncCpuTimeMillis = SystemClock.uptimeMillis();
42             if (mPreviousVSyncTimeMicros == 0) {
43                 mPreviousVSyncTimeMicros = vsyncTimeMicros;
44                 return;
45             }
46             if (mFrameCount >= mFramePeriods.length) {
47                 synchronized (mSyncRoot) {
48                     mDone = true;
49                     mSyncRoot.notify();
50                 }
51                 return;
52             }
53             mFramePeriods[mFrameCount++] = vsyncTimeMicros - mPreviousVSyncTimeMicros;
54             mPreviousVSyncTimeMicros = vsyncTimeMicros;
55             if (mActivelyRequestUpdate) monitor.requestUpdate();
56         }
57
58         public void waitTillDone() throws InterruptedException {
59             synchronized (mSyncRoot) {
60                 while (!isDone()) {
61                     mSyncRoot.wait();
62                 }
63             }
64         }
65     }
66
67     // The vsync monitor must be created on the UI thread to avoid associating the underlying
68     // Choreographer with the Looper from the test runner thread.
69     private VSyncMonitor createVSyncMonitor(
70             final VSyncMonitor.Listener listener, final boolean enableJBVSync) {
71         return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<VSyncMonitor>() {
72             @Override
73             public VSyncMonitor call() {
74                 Context context = getInstrumentation().getContext();
75                 return new VSyncMonitor(context, listener, enableJBVSync);
76             }
77         });
78     }
79
80     // Check that the vsync period roughly matches the timestamps that the monitor generates.
81     private void performVSyncPeriodTest(boolean enableJBVSync) throws InterruptedException {
82         // Collect roughly one second of data on a 60 fps display.
83         collectAndCheckVSync(enableJBVSync, 60, true);
84         collectAndCheckVSync(enableJBVSync, VSyncMonitor.MAX_AUTO_ONVSYNC_COUNT, false);
85     }
86
87     private void collectAndCheckVSync(
88             boolean enableJBVSync, final int totalFrames, final boolean activeFrames)
89             throws InterruptedException {
90         VSyncDataCollector collector = new VSyncDataCollector(totalFrames, activeFrames);
91         VSyncMonitor monitor = createVSyncMonitor(collector, enableJBVSync);
92
93         long reportedFramePeriod = monitor.getVSyncPeriodInMicroseconds();
94         assertTrue(reportedFramePeriod > 0);
95
96         assertFalse(collector.isDone());
97         monitor.requestUpdate();
98         collector.waitTillDone();
99         assertTrue(collector.isDone());
100         monitor.stop();
101
102         // Check that the median frame rate is within 10% of the reported frame period.
103         assertTrue(collector.mFrameCount == totalFrames);
104         Arrays.sort(collector.mFramePeriods, 0, collector.mFramePeriods.length);
105         long medianFramePeriod = collector.mFramePeriods[collector.mFramePeriods.length / 2];
106         if (Math.abs(medianFramePeriod - reportedFramePeriod) > reportedFramePeriod * .1) {
107             fail("Measured median frame period " + medianFramePeriod
108                     + " differs by more than 10% from the reported frame period "
109                     + reportedFramePeriod + " for "
110                     + (activeFrames ? "requested" : "automatically sent") + " frames");
111         }
112     }
113
114     // Check that the vsync period roughly matches the timestamps that the monitor generates.
115     @MediumTest
116     public void testVSyncPeriodAllowJBVSync() throws InterruptedException {
117         performVSyncPeriodTest(true);
118     }
119
120     // Check that the vsync period roughly matches the timestamps that the monitor generates.
121     @MediumTest
122     public void testVSyncPeriodDisallowJBVSync() throws InterruptedException {
123         performVSyncPeriodTest(false);
124     }
125
126     // Check that the vsync period roughly matches the timestamps that the monitor generates.
127     private void performVSyncActivationFromIdle(boolean enableJBVSync) throws InterruptedException {
128         VSyncDataCollector collector = new VSyncDataCollector(1, false);
129         VSyncMonitor monitor = createVSyncMonitor(collector, enableJBVSync);
130
131         monitor.requestUpdate();
132         collector.waitTillDone();
133         assertTrue(collector.isDone());
134         monitor.stop();
135
136         long period = monitor.getVSyncPeriodInMicroseconds() / 1000;
137         long delay = SystemClock.uptimeMillis() - collector.mLastVSyncCpuTimeMillis;
138
139         // The VSync should have activated immediately instead of at the next real vsync.
140         assertTrue(delay < period);
141     }
142
143     @MediumTest
144     public void testVSyncActivationFromIdleAllowJBVSync() throws InterruptedException {
145         performVSyncActivationFromIdle(true);
146     }
147
148     @MediumTest
149     public void testVSyncActivationFromIdleDisallowJBVSync() throws InterruptedException {
150         performVSyncActivationFromIdle(false);
151     }
152 }