Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(695)

Unified Diff: content/public/android/java/src/org/chromium/content/browser/VSyncMonitor.java

Issue 236193013: Android: Consolidate and simplify VSync logic (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/public/android/java/src/org/chromium/content/browser/VSyncMonitor.java
diff --git a/content/public/android/java/src/org/chromium/content/browser/VSyncMonitor.java b/content/public/android/java/src/org/chromium/content/browser/VSyncMonitor.java
deleted file mode 100644
index ce9f36dfd45b08e18b8ff184894575ac105f6f47..0000000000000000000000000000000000000000
--- a/content/public/android/java/src/org/chromium/content/browser/VSyncMonitor.java
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.content.browser;
-
-import android.content.Context;
-import android.os.Build;
-import android.os.Handler;
-import android.view.Choreographer;
-import android.view.WindowManager;
-
-import org.chromium.base.TraceEvent;
-
-/**
- * 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
- * approximation of a vertical sync starting point; see also http://crbug.com/156397.
- */
-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;
- public static final int MAX_AUTO_ONVSYNC_COUNT = 5;
-
- /**
- * VSync listener class
- */
- public interface Listener {
- /**
- * Called very soon after the start of the display's vertical sync period.
- * @param monitor The VSyncMonitor that triggered the signal.
- * @param vsyncTimeMicros Absolute frame time in microseconds.
- */
- public void onVSync(VSyncMonitor monitor, long vsyncTimeMicros);
- }
-
- private Listener mListener;
-
- // Display refresh rate as reported by the system.
- private final long mRefreshPeriodNano;
-
- private boolean mHaveRequestInFlight;
- private int mTriggerNextVSyncCount;
-
- // 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.
- private final Handler mHandler = new Handler();
- private final Runnable mSyntheticVSyncRunnable;
- private long mLastVSyncCpuTimeNano;
-
- public VSyncMonitor(Context context, VSyncMonitor.Listener listener) {
- this(context, listener, true);
- }
-
- VSyncMonitor(Context context, VSyncMonitor.Listener listener, boolean enableJBVSync) {
- mListener = listener;
- float refreshRate = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE))
- .getDefaultDisplay().getRefreshRate();
- if (refreshRate <= 0) refreshRate = 60;
- mRefreshPeriodNano = (long) (NANOSECONDS_PER_SECOND / refreshRate);
- mTriggerNextVSyncCount = 0;
-
- 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");
- 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");
- }
- };
- mLastPostedNano = 0;
- }
- mSyntheticVSyncRunnable = new Runnable() {
- @Override
- public void run() {
- TraceEvent.begin("VSyncSynthetic");
- final long currentTime = getCurrentNanoTime();
- onVSyncCallback(estimateLastVSyncTime(currentTime), currentTime);
- TraceEvent.end("VSyncSynthetic");
- }
- };
- mGoodStartingPointNano = getCurrentNanoTime();
- }
-
- /**
- * Returns the time interval between two consecutive vsync pulses in microseconds.
- */
- public long getVSyncPeriodInMicroseconds() {
- return mRefreshPeriodNano / NANOSECONDS_PER_MICROSECOND;
- }
-
- /**
- * Determine whether a true vsync signal is available on this platform.
- */
- public boolean isVSyncSignalAvailable() {
- 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;
- }
-
- /**
- * Unregister the listener.
- * No vsync events will be reported afterwards.
- */
- public void unregisterListener() {
- stop();
- mListener = null;
- }
-
- /**
- * Request to be notified of the closest display vsync events.
- * 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() {
- mTriggerNextVSyncCount = MAX_AUTO_ONVSYNC_COUNT;
- 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;
- }
-
- private long getCurrentNanoTime() {
- return System.nanoTime();
- }
-
- private void onVSyncCallback(long frameTimeNanos, long currentTimeNanos) {
- assert mHaveRequestInFlight;
- mHaveRequestInFlight = false;
- mLastVSyncCpuTimeNano = currentTimeNanos;
- if (mTriggerNextVSyncCount >= 0) {
- mTriggerNextVSyncCount--;
- postCallback();
- }
- if (mListener != null) {
- mListener.onVSync(this, frameTimeNanos / NANOSECONDS_PER_MICROSECOND);
- }
- }
-
- private void postCallback() {
- if (mHaveRequestInFlight) return;
- mHaveRequestInFlight = true;
- if (postSyntheticVSync()) return;
- if (isVSyncSignalAvailable()) {
- mChoreographer.postFrameCallback(mVSyncFrameCallback);
- } else {
- postRunnableCallback();
- }
- }
-
- private boolean postSyntheticVSync() {
- final long currentTime = getCurrentNanoTime();
- // Only trigger a synthetic vsync if we've been idle for long enough and the upcoming real
- // vsync is more than half a frame away.
- if (currentTime - mLastVSyncCpuTimeNano < 2 * mRefreshPeriodNano) return false;
- if (currentTime - estimateLastVSyncTime(currentTime) > mRefreshPeriodNano / 2) return false;
- mHandler.post(mSyntheticVSyncRunnable);
- return true;
- }
-
- private long estimateLastVSyncTime(long currentTime) {
- final long lastRefreshTime = mGoodStartingPointNano +
- ((currentTime - mGoodStartingPointNano) / mRefreshPeriodNano) * 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);
- }
-}

Powered by Google App Engine
This is Rietveld 408576698