Commit 962fc225 authored by aurimas's avatar aurimas Committed by Commit bot

Remove ICS support in VSyncMonitor.

Chrome no longer supports API 14 and 15

BUG=473837

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

Cr-Commit-Position: refs/heads/master@{#327170}
parent 628f9818
......@@ -20,6 +20,8 @@ import java.util.concurrent.Callable;
* Tests VSyncMonitor to make sure it generates correct VSync timestamps.
*/
public class VSyncMonitorTest extends InstrumentationTestCase {
private static final int FRAME_COUNT = 60;
private static class VSyncDataCollector implements VSyncMonitor.Listener {
public long mFramePeriods[];
public int mFrameCount;
......@@ -69,28 +71,22 @@ public class VSyncMonitorTest extends InstrumentationTestCase {
// The vsync monitor must be created on the UI thread to avoid associating the underlying
// Choreographer with the Looper from the test runner thread.
private VSyncMonitor createVSyncMonitor(
final VSyncMonitor.Listener listener, final boolean enableJBVSync) {
private VSyncMonitor createVSyncMonitor(final VSyncMonitor.Listener listener) {
return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<VSyncMonitor>() {
@Override
public VSyncMonitor call() {
Context context = getInstrumentation().getContext();
return new VSyncMonitor(context, listener, enableJBVSync);
return new VSyncMonitor(context, listener);
}
});
}
// Check that the vsync period roughly matches the timestamps that the monitor generates.
private void performVSyncPeriodTest(boolean enableJBVSync) throws InterruptedException {
@MediumTest
public void testVSyncPeriod() throws InterruptedException {
// Collect roughly one second of data on a 60 fps display.
collectAndCheckVSync(enableJBVSync, 60);
}
private void collectAndCheckVSync(
boolean enableJBVSync, final int totalFrames)
throws InterruptedException {
VSyncDataCollector collector = new VSyncDataCollector(totalFrames);
VSyncMonitor monitor = createVSyncMonitor(collector, enableJBVSync);
VSyncDataCollector collector = new VSyncDataCollector(FRAME_COUNT);
VSyncMonitor monitor = createVSyncMonitor(collector);
long reportedFramePeriod = monitor.getVSyncPeriodInMicroseconds();
assertTrue(reportedFramePeriod > 0);
......@@ -101,7 +97,7 @@ public class VSyncMonitorTest extends InstrumentationTestCase {
assertTrue(collector.isDone());
// Check that the median frame rate is within 10% of the reported frame period.
assertTrue(collector.mFrameCount == totalFrames - 1);
assertTrue(collector.mFrameCount == FRAME_COUNT - 1);
Arrays.sort(collector.mFramePeriods, 0, collector.mFramePeriods.length);
long medianFramePeriod = collector.mFramePeriods[collector.mFramePeriods.length / 2];
if (Math.abs(medianFramePeriod - reportedFramePeriod) > reportedFramePeriod * .1) {
......@@ -110,34 +106,21 @@ public class VSyncMonitorTest extends InstrumentationTestCase {
+ reportedFramePeriod + " for requested frames");
}
if (enableJBVSync) {
Context context = getInstrumentation().getContext();
float refreshRate = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay().getRefreshRate();
if (refreshRate < 30.0f) {
// Reported refresh rate is most likely incorrect.
// Estimated vsync period is expected to be lower than (1000000 / 30) microseconds
assertTrue(monitor.getVSyncPeriodInMicroseconds() < 1000000 / 30);
}
Context context = getInstrumentation().getContext();
float refreshRate = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay().getRefreshRate();
if (refreshRate < 30.0f) {
// Reported refresh rate is most likely incorrect.
// Estimated vsync period is expected to be lower than (1000000 / 30) microseconds
assertTrue(monitor.getVSyncPeriodInMicroseconds() < 1000000 / 30);
}
}
// Check that the vsync period roughly matches the timestamps that the monitor generates.
@MediumTest
public void testVSyncPeriodAllowJBVSync() throws InterruptedException {
performVSyncPeriodTest(true);
}
// Check that the vsync period roughly matches the timestamps that the monitor generates.
@MediumTest
public void testVSyncPeriodDisallowJBVSync() throws InterruptedException {
performVSyncPeriodTest(false);
}
// Check that the vsync period roughly matches the timestamps that the monitor generates.
private void performVSyncActivationFromIdle(boolean enableJBVSync) throws InterruptedException {
public void testVSyncActivationFromIdle() throws InterruptedException {
// Check that the vsync period roughly matches the timestamps that the monitor generates.
VSyncDataCollector collector = new VSyncDataCollector(1);
VSyncMonitor monitor = createVSyncMonitor(collector, enableJBVSync);
VSyncMonitor monitor = createVSyncMonitor(collector);
monitor.requestUpdate();
collector.waitTillDone();
......@@ -149,14 +132,4 @@ public class VSyncMonitorTest extends InstrumentationTestCase {
// The VSync should have activated immediately instead of at the next real vsync.
assertTrue(delay < period);
}
@MediumTest
public void testVSyncActivationFromIdleAllowJBVSync() throws InterruptedException {
performVSyncActivationFromIdle(true);
}
@MediumTest
public void testVSyncActivationFromIdleDisallowJBVSync() throws InterruptedException {
performVSyncActivationFromIdle(false);
}
}
......@@ -4,9 +4,7 @@
package org.chromium.ui;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.view.Choreographer;
import android.view.WindowManager;
......@@ -15,13 +13,9 @@ import org.chromium.base.TraceEvent;
/**
* Notifies clients of the default displays's vertical sync pulses.
* 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.
*/
@SuppressLint("NewApi")
public class VSyncMonitor {
private static final long NANOSECONDS_PER_SECOND = 1000000000;
private static final long NANOSECONDS_PER_MILLISECOND = 1000000;
private static final long NANOSECONDS_PER_MICROSECOND = 1000;
private boolean mInsideVSync = false;
......@@ -49,14 +43,9 @@ public class VSyncMonitor {
private boolean mHaveRequestInFlight;
// Choreographer is used to detect vsync on >= JB.
private final Choreographer mChoreographer;
private final Choreographer.FrameCallback mVSyncFrameCallback;
// On ICS we just post a task through the handler (http://crbug.com/156397)
private final Runnable mVSyncRunnableCallback;
private long mGoodStartingPointNano;
private long mLastPostedNano;
// If the monitor is activated after having been idle, we synthesize the first vsync to reduce
// latency.
......@@ -70,16 +59,6 @@ public class VSyncMonitor {
* @param listener The listener receiving VSync notifications.
*/
public VSyncMonitor(Context context, VSyncMonitor.Listener listener) {
this(context, listener, true);
}
/**
* Constructs a VSyncMonitor
* @param context The application context.
* @param listener The listener receiving VSync notifications.
* @param enableJBVsync Whether to allow Choreographer-based notifications on JB and up.
*/
public VSyncMonitor(Context context, VSyncMonitor.Listener listener, boolean enableJBVSync) {
mListener = listener;
float refreshRate = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay().getRefreshRate();
......@@ -88,43 +67,25 @@ public class VSyncMonitor {
if (refreshRate <= 0) refreshRate = 60;
mRefreshPeriodNano = (long) (NANOSECONDS_PER_SECOND / refreshRate);
if (enableJBVSync && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
// Use Choreographer on JB+ to get notified of vsync.
mChoreographer = Choreographer.getInstance();
mVSyncFrameCallback = new Choreographer.FrameCallback() {
@Override
public void doFrame(long frameTimeNanos) {
TraceEvent.begin("VSync");
if (useEstimatedRefreshPeriod && mConsecutiveVSync) {
// Display.getRefreshRate() is unreliable on some platforms.
// Adjust refresh period- initial value is based on Display.getRefreshRate()
// after that it asymptotically approaches the real value.
long lastRefreshDurationNano = frameTimeNanos - mGoodStartingPointNano;
float lastRefreshDurationWeight = 0.1f;
mRefreshPeriodNano += (long) (lastRefreshDurationWeight
* (lastRefreshDurationNano - mRefreshPeriodNano));
}
mGoodStartingPointNano = frameTimeNanos;
onVSyncCallback(frameTimeNanos, getCurrentNanoTime());
TraceEvent.end("VSync");
}
};
mVSyncRunnableCallback = null;
} else {
// On ICS we just hope that running tasks is relatively predictable.
mChoreographer = null;
mVSyncFrameCallback = null;
mVSyncRunnableCallback = new Runnable() {
@Override
public void run() {
TraceEvent.begin("VSyncTimer");
final long currentTime = getCurrentNanoTime();
onVSyncCallback(currentTime, currentTime);
TraceEvent.end("VSyncTimer");
mChoreographer = Choreographer.getInstance();
mVSyncFrameCallback = new Choreographer.FrameCallback() {
@Override
public void doFrame(long frameTimeNanos) {
TraceEvent.begin("VSync");
if (useEstimatedRefreshPeriod && mConsecutiveVSync) {
// Display.getRefreshRate() is unreliable on some platforms.
// Adjust refresh period- initial value is based on Display.getRefreshRate()
// after that it asymptotically approaches the real value.
long lastRefreshDurationNano = frameTimeNanos - mGoodStartingPointNano;
float lastRefreshDurationWeight = 0.1f;
mRefreshPeriodNano += (long) (lastRefreshDurationWeight
* (lastRefreshDurationNano - mRefreshPeriodNano));
}
};
mLastPostedNano = 0;
}
mGoodStartingPointNano = frameTimeNanos;
onVSyncCallback(frameTimeNanos, getCurrentNanoTime());
TraceEvent.end("VSync");
}
};
mSyntheticVSyncRunnable = new Runnable() {
@Override
public void run() {
......@@ -144,13 +105,6 @@ public class VSyncMonitor {
return mRefreshPeriodNano / NANOSECONDS_PER_MICROSECOND;
}
/**
* Determine whether a true vsync signal is available on this platform.
*/
private boolean isVSyncSignalAvailable() {
return mChoreographer != null;
}
/**
* Request to be notified of the closest display vsync events.
* Listener.onVSync() will be called soon after the upcoming vsync pulses.
......@@ -159,14 +113,6 @@ public class VSyncMonitor {
postCallback();
}
/**
* Set the best guess of the point in the past when the vsync has happened.
* @param goodStartingPointNano Known vsync point in the past.
*/
public void setVSyncPointForICS(long goodStartingPointNano) {
mGoodStartingPointNano = goodStartingPointNano;
}
/**
* @return true if onVSync handler is executing. If onVSync handler
* introduces invalidations, View#invalidate() should be called. If
......@@ -200,12 +146,8 @@ public class VSyncMonitor {
if (mHaveRequestInFlight) return;
mHaveRequestInFlight = true;
if (postSyntheticVSync()) return;
if (isVSyncSignalAvailable()) {
mConsecutiveVSync = mInsideVSync;
mChoreographer.postFrameCallback(mVSyncFrameCallback);
} else {
postRunnableCallback();
}
mConsecutiveVSync = mInsideVSync;
mChoreographer.postFrameCallback(mVSyncFrameCallback);
}
private boolean postSyntheticVSync() {
......@@ -224,20 +166,4 @@ public class VSyncMonitor {
* mRefreshPeriodNano;
return lastRefreshTime;
}
private void postRunnableCallback() {
assert !isVSyncSignalAvailable();
final long currentTime = getCurrentNanoTime();
final long lastRefreshTime = estimateLastVSyncTime(currentTime);
long delay = (lastRefreshTime + mRefreshPeriodNano) - currentTime;
assert delay > 0 && delay <= mRefreshPeriodNano;
if (currentTime + delay <= mLastPostedNano + mRefreshPeriodNano / 2) {
delay += mRefreshPeriodNano;
}
mLastPostedNano = currentTime + delay;
if (delay == 0) mHandler.post(mVSyncRunnableCallback);
else mHandler.postDelayed(mVSyncRunnableCallback, delay / NANOSECONDS_PER_MILLISECOND);
}
}
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