Remove burst mode from VSyncMonitor.

Extra vsyncs after each rendering cause 1% more power consumption.
Modify VSyncMonitorTest to follow the rule 1 request == 1 vsync.

BUG=

Review URL: https://codereview.chromium.org/377483002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@282154 0039d316-1c4b-4281-b951-d872f2087c98
parent 8ca7245d
...@@ -105,6 +105,7 @@ Douglas F. Turner <doug.turner@gmail.com> ...@@ -105,6 +105,7 @@ Douglas F. Turner <doug.turner@gmail.com>
Eduardo Lima (Etrunko) <eduardo.lima@intel.com> Eduardo Lima (Etrunko) <eduardo.lima@intel.com>
Edward Crossman <tedoc2000@gmail.com> Edward Crossman <tedoc2000@gmail.com>
Eero Häkkinen <e.hakkinen@partner.samsung.com> Eero Häkkinen <e.hakkinen@partner.samsung.com>
Egor Starkov <egor.starkov@samsung.com>
Ehsan Akhgari <ehsan.akhgari@gmail.com> Ehsan Akhgari <ehsan.akhgari@gmail.com>
Elan Ruusamäe <elan.ruusamae@gmail.com> Elan Ruusamäe <elan.ruusamae@gmail.com>
Eric Ahn <byungwook.ahn@gmail.com> Eric Ahn <byungwook.ahn@gmail.com>
......
...@@ -21,14 +21,12 @@ public class VSyncMonitorTest extends InstrumentationTestCase { ...@@ -21,14 +21,12 @@ public class VSyncMonitorTest extends InstrumentationTestCase {
public int mFrameCount; public int mFrameCount;
public long mLastVSyncCpuTimeMillis; public long mLastVSyncCpuTimeMillis;
private final boolean mActivelyRequestUpdate;
private boolean mDone; private boolean mDone;
private long mPreviousVSyncTimeMicros; private long mPreviousVSyncTimeMicros;
private Object mSyncRoot = new Object(); private Object mSyncRoot = new Object();
VSyncDataCollector(int frames, boolean activelyRequestUpdate) { VSyncDataCollector(int frames) {
mFramePeriods = new long[frames]; mFramePeriods = new long[frames - 1];
mActivelyRequestUpdate = activelyRequestUpdate;
} }
public boolean isDone() { public boolean isDone() {
...@@ -42,7 +40,10 @@ public class VSyncMonitorTest extends InstrumentationTestCase { ...@@ -42,7 +40,10 @@ public class VSyncMonitorTest extends InstrumentationTestCase {
mLastVSyncCpuTimeMillis = SystemClock.uptimeMillis(); mLastVSyncCpuTimeMillis = SystemClock.uptimeMillis();
if (mPreviousVSyncTimeMicros == 0) { if (mPreviousVSyncTimeMicros == 0) {
mPreviousVSyncTimeMicros = vsyncTimeMicros; mPreviousVSyncTimeMicros = vsyncTimeMicros;
return; }
else {
mFramePeriods[mFrameCount++] = vsyncTimeMicros - mPreviousVSyncTimeMicros;
mPreviousVSyncTimeMicros = vsyncTimeMicros;
} }
if (mFrameCount >= mFramePeriods.length) { if (mFrameCount >= mFramePeriods.length) {
synchronized (mSyncRoot) { synchronized (mSyncRoot) {
...@@ -51,9 +52,7 @@ public class VSyncMonitorTest extends InstrumentationTestCase { ...@@ -51,9 +52,7 @@ public class VSyncMonitorTest extends InstrumentationTestCase {
} }
return; return;
} }
mFramePeriods[mFrameCount++] = vsyncTimeMicros - mPreviousVSyncTimeMicros; monitor.requestUpdate();
mPreviousVSyncTimeMicros = vsyncTimeMicros;
if (mActivelyRequestUpdate) monitor.requestUpdate();
} }
public void waitTillDone() throws InterruptedException { public void waitTillDone() throws InterruptedException {
...@@ -81,14 +80,13 @@ public class VSyncMonitorTest extends InstrumentationTestCase { ...@@ -81,14 +80,13 @@ public class VSyncMonitorTest extends InstrumentationTestCase {
// Check that the vsync period roughly matches the timestamps that the monitor generates. // Check that the vsync period roughly matches the timestamps that the monitor generates.
private void performVSyncPeriodTest(boolean enableJBVSync) throws InterruptedException { private void performVSyncPeriodTest(boolean enableJBVSync) throws InterruptedException {
// Collect roughly one second of data on a 60 fps display. // Collect roughly one second of data on a 60 fps display.
collectAndCheckVSync(enableJBVSync, 60, true); collectAndCheckVSync(enableJBVSync, 60);
collectAndCheckVSync(enableJBVSync, VSyncMonitor.MAX_AUTO_ONVSYNC_COUNT, false);
} }
private void collectAndCheckVSync( private void collectAndCheckVSync(
boolean enableJBVSync, final int totalFrames, final boolean activeFrames) boolean enableJBVSync, final int totalFrames)
throws InterruptedException { throws InterruptedException {
VSyncDataCollector collector = new VSyncDataCollector(totalFrames, activeFrames); VSyncDataCollector collector = new VSyncDataCollector(totalFrames);
VSyncMonitor monitor = createVSyncMonitor(collector, enableJBVSync); VSyncMonitor monitor = createVSyncMonitor(collector, enableJBVSync);
long reportedFramePeriod = monitor.getVSyncPeriodInMicroseconds(); long reportedFramePeriod = monitor.getVSyncPeriodInMicroseconds();
...@@ -98,17 +96,15 @@ public class VSyncMonitorTest extends InstrumentationTestCase { ...@@ -98,17 +96,15 @@ public class VSyncMonitorTest extends InstrumentationTestCase {
monitor.requestUpdate(); monitor.requestUpdate();
collector.waitTillDone(); collector.waitTillDone();
assertTrue(collector.isDone()); assertTrue(collector.isDone());
monitor.stop();
// Check that the median frame rate is within 10% of the reported frame period. // Check that the median frame rate is within 10% of the reported frame period.
assertTrue(collector.mFrameCount == totalFrames); assertTrue(collector.mFrameCount == totalFrames - 1);
Arrays.sort(collector.mFramePeriods, 0, collector.mFramePeriods.length); Arrays.sort(collector.mFramePeriods, 0, collector.mFramePeriods.length);
long medianFramePeriod = collector.mFramePeriods[collector.mFramePeriods.length / 2]; long medianFramePeriod = collector.mFramePeriods[collector.mFramePeriods.length / 2];
if (Math.abs(medianFramePeriod - reportedFramePeriod) > reportedFramePeriod * .1) { if (Math.abs(medianFramePeriod - reportedFramePeriod) > reportedFramePeriod * .1) {
fail("Measured median frame period " + medianFramePeriod fail("Measured median frame period " + medianFramePeriod
+ " differs by more than 10% from the reported frame period " + " differs by more than 10% from the reported frame period "
+ reportedFramePeriod + " for " + reportedFramePeriod + " for requested frames");
+ (activeFrames ? "requested" : "automatically sent") + " frames");
} }
} }
...@@ -126,13 +122,12 @@ public class VSyncMonitorTest extends InstrumentationTestCase { ...@@ -126,13 +122,12 @@ public class VSyncMonitorTest extends InstrumentationTestCase {
// Check that the vsync period roughly matches the timestamps that the monitor generates. // Check that the vsync period roughly matches the timestamps that the monitor generates.
private void performVSyncActivationFromIdle(boolean enableJBVSync) throws InterruptedException { private void performVSyncActivationFromIdle(boolean enableJBVSync) throws InterruptedException {
VSyncDataCollector collector = new VSyncDataCollector(1, false); VSyncDataCollector collector = new VSyncDataCollector(1);
VSyncMonitor monitor = createVSyncMonitor(collector, enableJBVSync); VSyncMonitor monitor = createVSyncMonitor(collector, enableJBVSync);
monitor.requestUpdate(); monitor.requestUpdate();
collector.waitTillDone(); collector.waitTillDone();
assertTrue(collector.isDone()); assertTrue(collector.isDone());
monitor.stop();
long period = monitor.getVSyncPeriodInMicroseconds() / 1000; long period = monitor.getVSyncPeriodInMicroseconds() / 1000;
long delay = SystemClock.uptimeMillis() - collector.mLastVSyncCpuTimeMillis; long delay = SystemClock.uptimeMillis() - collector.mLastVSyncCpuTimeMillis;
......
...@@ -15,9 +15,6 @@ import org.chromium.base.TraceEvent; ...@@ -15,9 +15,6 @@ import org.chromium.base.TraceEvent;
/** /**
* Notifies clients of the default displays's vertical sync pulses. * Notifies clients of the default displays's vertical sync pulses.
* This class works in "burst" mode: once the update is requested, the listener will be
* called MAX_VSYNC_COUNT times on the vertical sync pulses (on JB) or on every refresh
* period (on ICS, see below), unless stop() is called.
* On ICS, VSyncMonitor relies on setVSyncPointForICS() being called to set a reasonable * On ICS, VSyncMonitor relies on setVSyncPointForICS() being called to set a reasonable
* approximation of a vertical sync starting point; see also http://crbug.com/156397. * approximation of a vertical sync starting point; see also http://crbug.com/156397.
*/ */
...@@ -26,7 +23,6 @@ public class VSyncMonitor { ...@@ -26,7 +23,6 @@ public class VSyncMonitor {
private static final long NANOSECONDS_PER_SECOND = 1000000000; private static final long NANOSECONDS_PER_SECOND = 1000000000;
private static final long NANOSECONDS_PER_MILLISECOND = 1000000; private static final long NANOSECONDS_PER_MILLISECOND = 1000000;
private static final long NANOSECONDS_PER_MICROSECOND = 1000; private static final long NANOSECONDS_PER_MICROSECOND = 1000;
public static final int MAX_AUTO_ONVSYNC_COUNT = 5;
/** /**
* VSync listener class * VSync listener class
...@@ -46,7 +42,6 @@ public class VSyncMonitor { ...@@ -46,7 +42,6 @@ public class VSyncMonitor {
private final long mRefreshPeriodNano; private final long mRefreshPeriodNano;
private boolean mHaveRequestInFlight; private boolean mHaveRequestInFlight;
private int mTriggerNextVSyncCount;
// Choreographer is used to detect vsync on >= JB. // Choreographer is used to detect vsync on >= JB.
private final Choreographer mChoreographer; private final Choreographer mChoreographer;
...@@ -84,7 +79,6 @@ public class VSyncMonitor { ...@@ -84,7 +79,6 @@ public class VSyncMonitor {
.getDefaultDisplay().getRefreshRate(); .getDefaultDisplay().getRefreshRate();
if (refreshRate <= 0) refreshRate = 60; if (refreshRate <= 0) refreshRate = 60;
mRefreshPeriodNano = (long) (NANOSECONDS_PER_SECOND / refreshRate); mRefreshPeriodNano = (long) (NANOSECONDS_PER_SECOND / refreshRate);
mTriggerNextVSyncCount = 0;
if (enableJBVSync && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { if (enableJBVSync && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
// Use Choreographer on JB+ to get notified of vsync. // Use Choreographer on JB+ to get notified of vsync.
...@@ -140,21 +134,11 @@ public class VSyncMonitor { ...@@ -140,21 +134,11 @@ public class VSyncMonitor {
return mChoreographer != null; return mChoreographer != null;
} }
/**
* Stop reporting vsync events. Note that at most one pending vsync event can still be delivered
* after this function is called.
*/
public void stop() {
mTriggerNextVSyncCount = 0;
}
/** /**
* Request to be notified of the closest display vsync events. * Request to be notified of the closest display vsync events.
* Listener.onVSync() will be called soon after the upcoming vsync pulses. * Listener.onVSync() will be called soon after the upcoming vsync pulses.
* It will be called at most MAX_AUTO_ONVSYNC_COUNT times unless requestUpdate() is called.
*/ */
public void requestUpdate() { public void requestUpdate() {
mTriggerNextVSyncCount = MAX_AUTO_ONVSYNC_COUNT;
postCallback(); postCallback();
} }
...@@ -174,10 +158,6 @@ public class VSyncMonitor { ...@@ -174,10 +158,6 @@ public class VSyncMonitor {
assert mHaveRequestInFlight; assert mHaveRequestInFlight;
mHaveRequestInFlight = false; mHaveRequestInFlight = false;
mLastVSyncCpuTimeNano = currentTimeNanos; mLastVSyncCpuTimeNano = currentTimeNanos;
if (mTriggerNextVSyncCount >= 0) {
mTriggerNextVSyncCount--;
postCallback();
}
if (mListener != null) { if (mListener != null) {
mListener.onVSync(this, frameTimeNanos / NANOSECONDS_PER_MICROSECOND); mListener.onVSync(this, frameTimeNanos / NANOSECONDS_PER_MICROSECOND);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment