OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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.ui; | 5 package org.chromium.ui; |
6 | 6 |
7 import android.annotation.SuppressLint; | 7 import android.annotation.SuppressLint; |
8 import android.content.Context; | 8 import android.content.Context; |
9 import android.os.Build; | 9 import android.os.Build; |
10 import android.os.Handler; | 10 import android.os.Handler; |
11 import android.view.Choreographer; | 11 import android.view.Choreographer; |
12 import android.view.WindowManager; | 12 import android.view.WindowManager; |
13 | 13 |
14 import org.chromium.base.TraceEvent; | 14 import org.chromium.base.TraceEvent; |
15 | 15 |
16 /** | 16 /** |
17 * Notifies clients of the default displays's vertical sync pulses. | 17 * Notifies clients of the default displays's vertical sync pulses. |
18 * On ICS, VSyncMonitor relies on setVSyncPointForICS() being called to set a re asonable | 18 * On ICS, VSyncMonitor relies on setVSyncPointForICS() being called to set a re asonable |
19 * approximation of a vertical sync starting point; see also http://crbug.com/15 6397. | 19 * approximation of a vertical sync starting point; see also http://crbug.com/15 6397. |
20 */ | 20 */ |
21 @SuppressLint("NewApi") | 21 @SuppressLint("NewApi") |
22 public class VSyncMonitor { | 22 public class VSyncMonitor { |
23 private static final long NANOSECONDS_PER_SECOND = 1000000000; | 23 private static final long NANOSECONDS_PER_SECOND = 1000000000; |
24 private static final long NANOSECONDS_PER_MILLISECOND = 1000000; | 24 private static final long NANOSECONDS_PER_MILLISECOND = 1000000; |
25 private static final long NANOSECONDS_PER_MICROSECOND = 1000; | 25 private static final long NANOSECONDS_PER_MICROSECOND = 1000; |
26 | 26 |
27 private boolean mInsideVSync = false; | |
28 | |
27 /** | 29 /** |
28 * VSync listener class | 30 * VSync listener class |
29 */ | 31 */ |
30 public interface Listener { | 32 public interface Listener { |
31 /** | 33 /** |
32 * Called very soon after the start of the display's vertical sync perio d. | 34 * Called very soon after the start of the display's vertical sync perio d. |
33 * @param monitor The VSyncMonitor that triggered the signal. | 35 * @param monitor The VSyncMonitor that triggered the signal. |
34 * @param vsyncTimeMicros Absolute frame time in microseconds. | 36 * @param vsyncTimeMicros Absolute frame time in microseconds. |
35 */ | 37 */ |
36 public void onVSync(VSyncMonitor monitor, long vsyncTimeMicros); | 38 public void onVSync(VSyncMonitor monitor, long vsyncTimeMicros); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
143 } | 145 } |
144 | 146 |
145 /** | 147 /** |
146 * Set the best guess of the point in the past when the vsync has happened. | 148 * Set the best guess of the point in the past when the vsync has happened. |
147 * @param goodStartingPointNano Known vsync point in the past. | 149 * @param goodStartingPointNano Known vsync point in the past. |
148 */ | 150 */ |
149 public void setVSyncPointForICS(long goodStartingPointNano) { | 151 public void setVSyncPointForICS(long goodStartingPointNano) { |
150 mGoodStartingPointNano = goodStartingPointNano; | 152 mGoodStartingPointNano = goodStartingPointNano; |
151 } | 153 } |
152 | 154 |
155 /** | |
156 * @return true if onVSync handler is executing. If onVSync handler | |
157 * introduces invalidations, View#invalidate() should be called. If | |
158 * View#postInvalidateOnAnimation is called instead, the corresponding onDra w | |
159 * will be delayed by one frame. The embedder of VSyncMonitor should check | |
160 * this value if it wants to post an invalidation. | |
161 */ | |
162 public boolean isInsideVSync() { | |
163 return mInsideVSync; | |
164 } | |
165 | |
153 private long getCurrentNanoTime() { | 166 private long getCurrentNanoTime() { |
154 return System.nanoTime(); | 167 return System.nanoTime(); |
155 } | 168 } |
156 | 169 |
157 private void onVSyncCallback(long frameTimeNanos, long currentTimeNanos) { | 170 private void onVSyncCallback(long frameTimeNanos, long currentTimeNanos) { |
158 assert mHaveRequestInFlight; | 171 assert mHaveRequestInFlight; |
172 mInsideVSync = true; | |
159 mHaveRequestInFlight = false; | 173 mHaveRequestInFlight = false; |
160 mLastVSyncCpuTimeNano = currentTimeNanos; | 174 mLastVSyncCpuTimeNano = currentTimeNanos; |
161 if (mListener != null) { | 175 try { |
162 mListener.onVSync(this, frameTimeNanos / NANOSECONDS_PER_MICROSECOND ); | 176 if (mListener != null) { |
177 mListener.onVSync(this, frameTimeNanos / NANOSECONDS_PER_MICROSE COND); | |
178 } | |
179 } | |
180 finally { | |
boliu
2014/08/20 20:30:00
nit: move finally one one above
| |
181 mInsideVSync = false; | |
163 } | 182 } |
164 } | 183 } |
165 | 184 |
166 private void postCallback() { | 185 private void postCallback() { |
167 if (mHaveRequestInFlight) return; | 186 if (mHaveRequestInFlight) return; |
168 mHaveRequestInFlight = true; | 187 mHaveRequestInFlight = true; |
169 if (postSyntheticVSync()) return; | 188 if (postSyntheticVSync()) return; |
170 if (isVSyncSignalAvailable()) { | 189 if (isVSyncSignalAvailable()) { |
171 mChoreographer.postFrameCallback(mVSyncFrameCallback); | 190 mChoreographer.postFrameCallback(mVSyncFrameCallback); |
172 } else { | 191 } else { |
(...skipping 26 matching lines...) Expand all Loading... | |
199 | 218 |
200 if (currentTime + delay <= mLastPostedNano + mRefreshPeriodNano / 2) { | 219 if (currentTime + delay <= mLastPostedNano + mRefreshPeriodNano / 2) { |
201 delay += mRefreshPeriodNano; | 220 delay += mRefreshPeriodNano; |
202 } | 221 } |
203 | 222 |
204 mLastPostedNano = currentTime + delay; | 223 mLastPostedNano = currentTime + delay; |
205 if (delay == 0) mHandler.post(mVSyncRunnableCallback); | 224 if (delay == 0) mHandler.post(mVSyncRunnableCallback); |
206 else mHandler.postDelayed(mVSyncRunnableCallback, delay / NANOSECONDS_PE R_MILLISECOND); | 225 else mHandler.postDelayed(mVSyncRunnableCallback, delay / NANOSECONDS_PE R_MILLISECOND); |
207 } | 226 } |
208 } | 227 } |
OLD | NEW |