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