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

Side by Side Diff: content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java

Issue 236193013: Android: Consolidate and simplify VSync logic (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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.graphics.Bitmap; 8 import android.graphics.Bitmap;
9 import android.graphics.Canvas; 9 import android.graphics.Canvas;
10 import android.graphics.Color; 10 import android.graphics.Color;
11 import android.graphics.PixelFormat; 11 import android.graphics.PixelFormat;
12 import android.os.Build;
13 import android.os.Handler; 12 import android.os.Handler;
14 import android.view.Surface; 13 import android.view.Surface;
15 import android.view.SurfaceHolder; 14 import android.view.SurfaceHolder;
16 import android.view.SurfaceView; 15 import android.view.SurfaceView;
17 import android.widget.FrameLayout; 16 import android.widget.FrameLayout;
18 17
19 import org.chromium.base.CalledByNative; 18 import org.chromium.base.CalledByNative;
20 import org.chromium.base.JNINamespace; 19 import org.chromium.base.JNINamespace;
21 import org.chromium.base.ObserverList;
22 import org.chromium.base.ObserverList.RewindableIterator;
23 import org.chromium.base.TraceEvent; 20 import org.chromium.base.TraceEvent;
24 import org.chromium.ui.base.WindowAndroid; 21 import org.chromium.ui.base.WindowAndroid;
25 22
26 /*** 23 /***
27 * This view is used by a ContentView to render its content. 24 * This view is used by a ContentView to render its content.
28 * Call {@link #setCurrentContentViewCore(ContentViewCore)} with the contentView Core that should be 25 * Call {@link #setCurrentContentViewCore(ContentViewCore)} with the contentView Core that should be
29 * managing the view. 26 * managing the view.
30 * Note that only one ContentViewCore can be shown at a time. 27 * Note that only one ContentViewCore can be shown at a time.
31 */ 28 */
32 @JNINamespace("content") 29 @JNINamespace("content")
33 public class ContentViewRenderView extends FrameLayout { 30 public class ContentViewRenderView extends FrameLayout implements WindowAndroid. VSyncClient {
David Trainor- moved to gerrit 2014/04/16 06:18:20 Indent +8
no sievers 2014/04/25 22:23:33 there's actually no line break here :)
34 private static final int MAX_SWAP_BUFFER_COUNT = 2; 31 private static final int MAX_SWAP_BUFFER_COUNT = 2;
35 32
36 // The native side of this object. 33 // The native side of this object.
37 private long mNativeContentViewRenderView; 34 private long mNativeContentViewRenderView;
38 private final SurfaceHolder.Callback mSurfaceCallback; 35 private final SurfaceHolder.Callback mSurfaceCallback;
39 36
40 private final SurfaceView mSurfaceView; 37 private final SurfaceView mSurfaceView;
41 private final VSyncAdapter mVSyncAdapter; 38 private final WindowAndroid mRootWindow;
42 39
43 private int mPendingRenders; 40 private int mPendingRenders;
44 private int mPendingSwapBuffers; 41 private int mPendingSwapBuffers;
45 private boolean mNeedToRender; 42 private boolean mNeedToRender;
46 43
47 private ContentViewCore mContentViewCore; 44 private ContentViewCore mContentViewCore;
48 45
49 private final Runnable mRenderRunnable = new Runnable() { 46 private final Runnable mRenderRunnable = new Runnable() {
50 @Override 47 @Override
51 public void run() { 48 public void run() {
52 render(); 49 render();
53 } 50 }
54 }; 51 };
55 52
56 /** 53 /**
57 * Constructs a new ContentViewRenderView that should be can to a view hiera rchy. 54 * Constructs a new ContentViewRenderView that should be can to a view hiera rchy.
58 * Native code should add/remove the layers to be rendered through the Conte ntViewLayerRenderer. 55 * Native code should add/remove the layers to be rendered through the Conte ntViewLayerRenderer.
59 * @param context The context used to create this. 56 * @param context The context used to create this.
60 */ 57 */
61 public ContentViewRenderView(Context context, WindowAndroid rootWindow) { 58 public ContentViewRenderView(Context context, WindowAndroid rootWindow) {
62 super(context); 59 super(context);
63 assert rootWindow != null; 60 assert rootWindow != null;
64 mNativeContentViewRenderView = nativeInit(rootWindow.getNativePointer()) ; 61 mNativeContentViewRenderView = nativeInit(rootWindow.getNativePointer()) ;
65 assert mNativeContentViewRenderView != 0; 62 assert mNativeContentViewRenderView != 0;
66 63
64 mRootWindow = rootWindow;
65 rootWindow.setVSyncClient(this);
67 mSurfaceView = createSurfaceView(getContext()); 66 mSurfaceView = createSurfaceView(getContext());
68 mSurfaceView.setZOrderMediaOverlay(true); 67 mSurfaceView.setZOrderMediaOverlay(true);
69 mSurfaceCallback = new SurfaceHolder.Callback() { 68 mSurfaceCallback = new SurfaceHolder.Callback() {
70 @Override 69 @Override
71 public void surfaceChanged(SurfaceHolder holder, int format, int wid th, int height) { 70 public void surfaceChanged(SurfaceHolder holder, int format, int wid th, int height) {
72 assert mNativeContentViewRenderView != 0; 71 assert mNativeContentViewRenderView != 0;
73 nativeSurfaceChanged(mNativeContentViewRenderView, 72 nativeSurfaceChanged(mNativeContentViewRenderView,
74 format, width, height, holder.getSurface()); 73 format, width, height, holder.getSurface());
75 if (mContentViewCore != null) { 74 if (mContentViewCore != null) {
76 mContentViewCore.onPhysicalBackingSizeChanged( 75 mContentViewCore.onPhysicalBackingSizeChanged(
(...skipping 15 matching lines...) Expand all
92 } 91 }
93 92
94 @Override 93 @Override
95 public void surfaceDestroyed(SurfaceHolder holder) { 94 public void surfaceDestroyed(SurfaceHolder holder) {
96 assert mNativeContentViewRenderView != 0; 95 assert mNativeContentViewRenderView != 0;
97 nativeSurfaceDestroyed(mNativeContentViewRenderView); 96 nativeSurfaceDestroyed(mNativeContentViewRenderView);
98 } 97 }
99 }; 98 };
100 mSurfaceView.getHolder().addCallback(mSurfaceCallback); 99 mSurfaceView.getHolder().addCallback(mSurfaceCallback);
101 100
102 mVSyncAdapter = new VSyncAdapter(getContext());
103 addView(mSurfaceView, 101 addView(mSurfaceView,
104 new FrameLayout.LayoutParams( 102 new FrameLayout.LayoutParams(
105 FrameLayout.LayoutParams.MATCH_PARENT, 103 FrameLayout.LayoutParams.MATCH_PARENT,
106 FrameLayout.LayoutParams.MATCH_PARENT)); 104 FrameLayout.LayoutParams.MATCH_PARENT));
107 } 105 }
108 106
109 private class VSyncAdapter implements VSyncManager.Provider, VSyncMonitor.Li stener { 107 @Override
110 private final VSyncMonitor mVSyncMonitor; 108 public void onVSync(long vsyncTimeMicros) {
111 private boolean mVSyncNotificationEnabled; 109 if (mNeedToRender) {
112 private VSyncManager.Listener mVSyncListener; 110 if (mPendingSwapBuffers + mPendingRenders <= MAX_SWAP_BUFFER_COUNT) {
113 private final ObserverList<VSyncManager.Listener> mCurrentVSyncListeners ; 111 mNeedToRender = false;
114 private final RewindableIterator<VSyncManager.Listener> mCurrentVSyncLis tenersIterator; 112 mPendingRenders++;
115 113 render();
116 // The VSyncMonitor gives the timebase for the actual vsync, but we don' t want render until 114 } else {
117 // we have had a chance for input events to propagate to the compositor thread. This takes 115 TraceEvent.instant("ContentViewRenderView:bail");
118 // 3 ms typically, so we adjust the vsync timestamps forward by a bit to give input events a
119 // chance to arrive.
120 private static final long INPUT_EVENT_LAG_FROM_VSYNC_MICROSECONDS = 3200 ;
Sami 2014/04/16 17:26:54 Should probably verify with a trace, but does the
no sievers 2014/04/25 22:23:33 I thought that the deadline scheduler and retroact
121
122 VSyncAdapter(Context context) {
123 mVSyncMonitor = new VSyncMonitor(context, this);
124 mCurrentVSyncListeners = new ObserverList<VSyncManager.Listener>();
125 mCurrentVSyncListenersIterator = mCurrentVSyncListeners.rewindableIt erator();
126 } 116 }
127 117 }
128 @Override
129 public void onVSync(VSyncMonitor monitor, long vsyncTimeMicros) {
130 if (mNeedToRender) {
131 if (mPendingSwapBuffers + mPendingRenders <= MAX_SWAP_BUFFER_COU NT) {
132 mNeedToRender = false;
133 mPendingRenders++;
134 render();
135 } else {
136 TraceEvent.instant("ContentViewRenderView:bail");
137 }
138 }
139
140 if (mVSyncListener != null) {
141 if (mVSyncNotificationEnabled) {
142 for (mCurrentVSyncListenersIterator.rewind();
143 mCurrentVSyncListenersIterator.hasNext();) {
144 mCurrentVSyncListenersIterator.next().onVSync(vsyncTimeM icros);
145 }
146 mVSyncMonitor.requestUpdate();
147 } else {
148 // Compensate for input event lag. Input events are delivere d immediately on
149 // pre-JB releases, so this adjustment is only done for late r versions.
150 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
151 vsyncTimeMicros += INPUT_EVENT_LAG_FROM_VSYNC_MICROSECON DS;
152 }
153 mVSyncListener.updateVSync(vsyncTimeMicros,
154 mVSyncMonitor.getVSyncPeriodInMicroseconds());
155 }
156 }
157 }
158
159 @Override
160 public void registerVSyncListener(VSyncManager.Listener listener) {
161 if (!mVSyncNotificationEnabled) mVSyncMonitor.requestUpdate();
162 mCurrentVSyncListeners.addObserver(listener);
163 mVSyncNotificationEnabled = true;
164 }
165
166 @Override
167 public void unregisterVSyncListener(VSyncManager.Listener listener) {
168 mCurrentVSyncListeners.removeObserver(listener);
169 if (mCurrentVSyncListeners.isEmpty()) {
170 mVSyncNotificationEnabled = false;
171 }
172 }
173
174 void setVSyncListener(VSyncManager.Listener listener) {
175 mVSyncListener = listener;
176 if (mVSyncListener != null) mVSyncMonitor.requestUpdate();
177 }
178
179 void requestUpdate() {
180 mVSyncMonitor.requestUpdate();
181 }
182 } 118 }
183 119
184 /** 120 /**
185 * Sets the background color of the surface view. This method is necessary because the 121 * Sets the background color of the surface view. This method is necessary because the
186 * background color of ContentViewRenderView itself is covered by the backgr ound of 122 * background color of ContentViewRenderView itself is covered by the backgr ound of
187 * SurfaceView. 123 * SurfaceView.
188 * @param color The color of the background. 124 * @param color The color of the background.
189 */ 125 */
190 public void setSurfaceViewBackgroundColor(int color) { 126 public void setSurfaceViewBackgroundColor(int color) {
191 if (mSurfaceView != null) { 127 if (mSurfaceView != null) {
192 mSurfaceView.setBackgroundColor(color); 128 mSurfaceView.setBackgroundColor(color);
193 } 129 }
194 } 130 }
195 131
196 /** 132 /**
197 * Should be called when the ContentViewRenderView is not needed anymore so its associated 133 * Should be called when the ContentViewRenderView is not needed anymore so its associated
198 * native resource can be freed. 134 * native resource can be freed.
199 */ 135 */
200 public void destroy() { 136 public void destroy() {
137 mRootWindow.setVSyncClient(null);
201 mSurfaceView.getHolder().removeCallback(mSurfaceCallback); 138 mSurfaceView.getHolder().removeCallback(mSurfaceCallback);
202 nativeDestroy(mNativeContentViewRenderView); 139 nativeDestroy(mNativeContentViewRenderView);
203 mNativeContentViewRenderView = 0; 140 mNativeContentViewRenderView = 0;
204 } 141 }
205 142
206 /** 143 /**
207 * Makes the passed ContentView the one displayed by this ContentViewRenderV iew. 144 * Makes the passed ContentView the one displayed by this ContentViewRenderV iew.
208 * TODO(yfriedman): Remove once this rolls downstream and callers are update d. 145 * TODO(yfriedman): Remove once this rolls downstream and callers are update d.
209 */ 146 */
210 @Deprecated 147 @Deprecated
211 public void setCurrentContentView(ContentView contentView) { 148 public void setCurrentContentView(ContentView contentView) {
212 setCurrentContentViewCore(contentView != null ? contentView.getContentVi ewCore() : null); 149 setCurrentContentViewCore(contentView != null ? contentView.getContentVi ewCore() : null);
213 } 150 }
214 151
215 152
216 public void setCurrentContentViewCore(ContentViewCore contentViewCore) { 153 public void setCurrentContentViewCore(ContentViewCore contentViewCore) {
217 assert mNativeContentViewRenderView != 0; 154 assert mNativeContentViewRenderView != 0;
218 mContentViewCore = contentViewCore; 155 mContentViewCore = contentViewCore;
219 156
220 if (mContentViewCore != null) { 157 if (mContentViewCore != null) {
221 mContentViewCore.onPhysicalBackingSizeChanged(getWidth(), getHeight( )); 158 mContentViewCore.onPhysicalBackingSizeChanged(getWidth(), getHeight( ));
222 mVSyncAdapter.setVSyncListener(mContentViewCore.getVSyncListener(mVS yncAdapter));
223 nativeSetCurrentContentViewCore(mNativeContentViewRenderView, 159 nativeSetCurrentContentViewCore(mNativeContentViewRenderView,
224 mContentViewCore.getNativeContentVie wCore()); 160 mContentViewCore.getNativeContentVie wCore());
225 } else { 161 } else {
226 nativeSetCurrentContentViewCore(mNativeContentViewRenderView, 0); 162 nativeSetCurrentContentViewCore(mNativeContentViewRenderView, 0);
227 } 163 }
228 } 164 }
229 165
230 /** 166 /**
231 * This method should be subclassed to provide actions to be performed once the view is ready to 167 * This method should be subclassed to provide actions to be performed once the view is ready to
232 * render. 168 * render.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 220
285 // The handler can be null if we are detached from the window. Call ing 221 // The handler can be null if we are detached from the window. Call ing
286 // {@link View#post(Runnable)} properly handles this case, but we lo se the front of 222 // {@link View#post(Runnable)} properly handles this case, but we lo se the front of
287 // queue behavior. That is okay for this edge case. 223 // queue behavior. That is okay for this edge case.
288 Handler handler = getHandler(); 224 Handler handler = getHandler();
289 if (handler != null) { 225 if (handler != null) {
290 handler.postAtFrontOfQueue(mRenderRunnable); 226 handler.postAtFrontOfQueue(mRenderRunnable);
291 } else { 227 } else {
292 post(mRenderRunnable); 228 post(mRenderRunnable);
293 } 229 }
294 mVSyncAdapter.requestUpdate();
295 } else if (mPendingRenders <= 0) { 230 } else if (mPendingRenders <= 0) {
296 assert mPendingRenders == 0; 231 assert mPendingRenders == 0;
297 TraceEvent.instant("requestRender:later"); 232 TraceEvent.instant("requestRender:later");
298 mNeedToRender = true; 233 mNeedToRender = true;
299 mVSyncAdapter.requestUpdate(); 234 mRootWindow.requestVSyncUpdate();
300 } 235 }
301 } 236 }
302 237
303 @CalledByNative 238 @CalledByNative
304 private void onSwapBuffersCompleted() { 239 private void onSwapBuffersCompleted() {
305 TraceEvent.instant("onSwapBuffersCompleted"); 240 TraceEvent.instant("onSwapBuffersCompleted");
306 241
307 if (mPendingSwapBuffers == MAX_SWAP_BUFFER_COUNT && mNeedToRender) reque stRender(); 242 if (mPendingSwapBuffers == MAX_SWAP_BUFFER_COUNT && mNeedToRender) reque stRender();
308 if (mPendingSwapBuffers > 0) mPendingSwapBuffers--; 243 if (mPendingSwapBuffers > 0) mPendingSwapBuffers--;
309 } 244 }
(...skipping 27 matching lines...) Expand all
337 long nativeContentViewCore); 272 long nativeContentViewCore);
338 private native void nativeSurfaceCreated(long nativeContentViewRenderView); 273 private native void nativeSurfaceCreated(long nativeContentViewRenderView);
339 private native void nativeSurfaceDestroyed(long nativeContentViewRenderView) ; 274 private native void nativeSurfaceDestroyed(long nativeContentViewRenderView) ;
340 private native void nativeSurfaceChanged(long nativeContentViewRenderView, 275 private native void nativeSurfaceChanged(long nativeContentViewRenderView,
341 int format, int width, int height, Surface surface); 276 int format, int width, int height, Surface surface);
342 private native boolean nativeComposite(long nativeContentViewRenderView); 277 private native boolean nativeComposite(long nativeContentViewRenderView);
343 private native boolean nativeCompositeToBitmap(long nativeContentViewRenderV iew, Bitmap bitmap); 278 private native boolean nativeCompositeToBitmap(long nativeContentViewRenderV iew, Bitmap bitmap);
344 private native void nativeSetOverlayVideoMode(long nativeContentViewRenderVi ew, 279 private native void nativeSetOverlayVideoMode(long nativeContentViewRenderVi ew,
345 boolean enabled); 280 boolean enabled);
346 } 281 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698