OLD | NEW |
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; |
(...skipping 25 matching lines...) Expand all Loading... |
36 private long mNativeContentViewRenderView; | 36 private long mNativeContentViewRenderView; |
37 private final SurfaceHolder.Callback mSurfaceCallback; | 37 private final SurfaceHolder.Callback mSurfaceCallback; |
38 | 38 |
39 private final SurfaceView mSurfaceView; | 39 private final SurfaceView mSurfaceView; |
40 private final VSyncAdapter mVSyncAdapter; | 40 private final VSyncAdapter mVSyncAdapter; |
41 | 41 |
42 private int mPendingRenders; | 42 private int mPendingRenders; |
43 private int mPendingSwapBuffers; | 43 private int mPendingSwapBuffers; |
44 private boolean mNeedToRender; | 44 private boolean mNeedToRender; |
45 | 45 |
46 private ContentView mCurrentContentView; | 46 protected ContentView mCurrentContentView; |
47 | 47 |
48 private final Runnable mRenderRunnable = new Runnable() { | 48 private final Runnable mRenderRunnable = new Runnable() { |
49 @Override | 49 @Override |
50 public void run() { | 50 public void run() { |
51 render(); | 51 render(); |
52 } | 52 } |
53 }; | 53 }; |
54 | 54 |
55 /** | 55 /** |
56 * Constructs a new ContentViewRenderView that should be can to a view hiera
rchy. | 56 * Constructs a new ContentViewRenderView that should be can to a view hiera
rchy. |
57 * Native code should add/remove the layers to be rendered through the Conte
ntViewLayerRenderer. | 57 * Native code should add/remove the layers to be rendered through the Conte
ntViewLayerRenderer. |
58 * @param context The context used to create this. | 58 * @param context The context used to create this. |
59 */ | 59 */ |
60 public ContentViewRenderView(Context context, WindowAndroid rootWindow) { | 60 public ContentViewRenderView(Context context, WindowAndroid rootWindow) { |
61 super(context); | 61 super(context); |
62 assert rootWindow != null; | 62 assert rootWindow != null; |
63 mNativeContentViewRenderView = nativeInit(rootWindow.getNativePointer())
; | 63 nativeInit(rootWindow.getNativePointer()); |
64 assert mNativeContentViewRenderView != 0; | 64 assert mNativeContentViewRenderView != 0; |
65 | 65 |
66 mSurfaceView = createSurfaceView(getContext()); | 66 mSurfaceView = createSurfaceView(getContext()); |
67 mSurfaceView.setZOrderMediaOverlay(true); | 67 mSurfaceView.setZOrderMediaOverlay(true); |
68 mSurfaceCallback = new SurfaceHolder.Callback() { | 68 mSurfaceCallback = new SurfaceHolder.Callback() { |
69 @Override | 69 @Override |
70 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) { |
71 assert mNativeContentViewRenderView != 0; | 71 assert mNativeContentViewRenderView != 0; |
72 nativeSurfaceChanged(mNativeContentViewRenderView, | 72 nativeSurfaceChanged(mNativeContentViewRenderView, |
73 format, width, height, holder.getSurface()); | 73 format, width, height, holder.getSurface()); |
74 if (mCurrentContentView != null) { | 74 if (mCurrentContentView != null) { |
75 mCurrentContentView.getContentViewCore().onPhysicalBackingSi
zeChanged( | 75 mCurrentContentView.getContentViewCore().onPhysicalBackingSi
zeChanged( |
76 width, height); | 76 width, height); |
77 } | 77 } |
78 } | 78 } |
79 | 79 |
80 @Override | 80 @Override |
81 public void surfaceCreated(SurfaceHolder holder) { | 81 public void surfaceCreated(SurfaceHolder holder) { |
82 setSurfaceViewBackgroundColor(Color.WHITE); | 82 ContentViewRenderView.this.surfaceCreated(); |
83 | |
84 assert mNativeContentViewRenderView != 0; | |
85 nativeSurfaceCreated(mNativeContentViewRenderView); | |
86 | |
87 mPendingSwapBuffers = 0; | |
88 mPendingRenders = 0; | |
89 | |
90 onReadyToRender(); | 83 onReadyToRender(); |
91 } | 84 } |
92 | 85 |
93 @Override | 86 @Override |
94 public void surfaceDestroyed(SurfaceHolder holder) { | 87 public void surfaceDestroyed(SurfaceHolder holder) { |
95 assert mNativeContentViewRenderView != 0; | 88 assert mNativeContentViewRenderView != 0; |
96 nativeSurfaceDestroyed(mNativeContentViewRenderView); | 89 nativeSurfaceDestroyed(mNativeContentViewRenderView); |
97 } | 90 } |
98 }; | 91 }; |
99 mSurfaceView.getHolder().addCallback(mSurfaceCallback); | 92 mSurfaceView.getHolder().addCallback(mSurfaceCallback); |
100 | 93 |
101 mVSyncAdapter = new VSyncAdapter(getContext()); | 94 mVSyncAdapter = new VSyncAdapter(getContext()); |
102 addView(mSurfaceView, | 95 addView(mSurfaceView, |
103 new FrameLayout.LayoutParams( | 96 new FrameLayout.LayoutParams( |
104 FrameLayout.LayoutParams.MATCH_PARENT, | 97 FrameLayout.LayoutParams.MATCH_PARENT, |
105 FrameLayout.LayoutParams.MATCH_PARENT)); | 98 FrameLayout.LayoutParams.MATCH_PARENT)); |
106 } | 99 } |
107 | 100 |
| 101 @CalledByNative |
| 102 private void clearNativePtr() { |
| 103 assert mNativeContentViewRenderView != 0; |
| 104 mNativeContentViewRenderView = 0; |
| 105 } |
| 106 |
| 107 @CalledByNative |
| 108 private void setNativePtr(long nativePtr) { |
| 109 assert mNativeContentViewRenderView == 0; |
| 110 mNativeContentViewRenderView = nativePtr; |
| 111 } |
| 112 |
108 private class VSyncAdapter implements VSyncManager.Provider, VSyncMonitor.Li
stener { | 113 private class VSyncAdapter implements VSyncManager.Provider, VSyncMonitor.Li
stener { |
109 private final VSyncMonitor mVSyncMonitor; | 114 private final VSyncMonitor mVSyncMonitor; |
110 private boolean mVSyncNotificationEnabled; | 115 private boolean mVSyncNotificationEnabled; |
111 private VSyncManager.Listener mVSyncListener; | 116 private VSyncManager.Listener mVSyncListener; |
112 private final ObserverList<VSyncManager.Listener> mCurrentVSyncListeners
; | 117 private final ObserverList<VSyncManager.Listener> mCurrentVSyncListeners
; |
113 private final RewindableIterator<VSyncManager.Listener> mCurrentVSyncLis
tenersIterator; | 118 private final RewindableIterator<VSyncManager.Listener> mCurrentVSyncLis
tenersIterator; |
114 | 119 |
115 // The VSyncMonitor gives the timebase for the actual vsync, but we don'
t want render until | 120 // The VSyncMonitor gives the timebase for the actual vsync, but we don'
t want render until |
116 // we have had a chance for input events to propagate to the compositor
thread. This takes | 121 // we have had a chance for input events to propagate to the compositor
thread. This takes |
117 // 3 ms typically, so we adjust the vsync timestamps forward by a bit to
give input events a | 122 // 3 ms typically, so we adjust the vsync timestamps forward by a bit to
give input events a |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 mCurrentContentView = contentView; | 216 mCurrentContentView = contentView; |
212 | 217 |
213 ContentViewCore contentViewCore = | 218 ContentViewCore contentViewCore = |
214 contentView != null ? contentView.getContentViewCore() : null; | 219 contentView != null ? contentView.getContentViewCore() : null; |
215 | 220 |
216 nativeSetCurrentContentView(mNativeContentViewRenderView, | 221 nativeSetCurrentContentView(mNativeContentViewRenderView, |
217 contentViewCore != null ? contentViewCore.getNativeContentViewCo
re() : 0); | 222 contentViewCore != null ? contentViewCore.getNativeContentViewCo
re() : 0); |
218 | 223 |
219 if (contentViewCore != null) { | 224 if (contentViewCore != null) { |
220 contentViewCore.onPhysicalBackingSizeChanged(getWidth(), getHeight()
); | 225 contentViewCore.onPhysicalBackingSizeChanged(getWidth(), getHeight()
); |
221 mVSyncAdapter.setVSyncListener(contentViewCore.getVSyncListener(mVSy
ncAdapter)); | 226 setVSyncListener(contentViewCore); |
222 } | 227 } |
223 } | 228 } |
224 | 229 |
225 /** | 230 /** |
226 * This method should be subclassed to provide actions to be performed once
the view is ready to | 231 * This method should be subclassed to provide actions to be performed once
the view is ready to |
227 * render. | 232 * render. |
228 */ | 233 */ |
229 protected void onReadyToRender() { | 234 protected void onReadyToRender() { |
230 } | 235 } |
231 | 236 |
232 /** | 237 /** |
| 238 * Gives inheriting classes a way to carry out tasks on the surfaceCreated()
call |
| 239 * for mSurfaceCallback. |
| 240 */ |
| 241 protected void surfaceCreated() { |
| 242 setSurfaceViewBackgroundColor(Color.WHITE); |
| 243 |
| 244 assert mNativeContentViewRenderView != 0; |
| 245 nativeSurfaceCreated(mNativeContentViewRenderView); |
| 246 |
| 247 mPendingSwapBuffers = 0; |
| 248 mPendingRenders = 0; |
| 249 } |
| 250 |
| 251 /** |
233 * This method could be subclassed optionally to provide a custom SurfaceVie
w object to | 252 * This method could be subclassed optionally to provide a custom SurfaceVie
w object to |
234 * this ContentViewRenderView. | 253 * this ContentViewRenderView. |
235 * @param context The context used to create the SurfaceView object. | 254 * @param context The context used to create the SurfaceView object. |
236 * @return The created SurfaceView object. | 255 * @return The created SurfaceView object. |
237 */ | 256 */ |
238 protected SurfaceView createSurfaceView(Context context) { | 257 protected SurfaceView createSurfaceView(Context context) { |
239 return new SurfaceView(context) { | 258 return new SurfaceView(context) { |
240 @Override | 259 @Override |
241 public void onDraw(Canvas canvas) { | 260 public void onDraw(Canvas canvas) { |
242 // We only need to draw to software canvases, which are used for
taking screenshots. | 261 // We only need to draw to software canvases, which are used for
taking screenshots. |
243 if (canvas.isHardwareAccelerated()) return; | 262 if (canvas.isHardwareAccelerated()) return; |
244 Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), | 263 Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), |
245 Bitmap.Config.ARGB_8888); | 264 Bitmap.Config.ARGB_8888); |
246 if (nativeCompositeToBitmap(mNativeContentViewRenderView, bitmap
)) { | 265 if (nativeCompositeToBitmap(mNativeContentViewRenderView, bitmap
)) { |
247 canvas.drawBitmap(bitmap, 0, 0, null); | 266 canvas.drawBitmap(bitmap, 0, 0, null); |
248 } | 267 } |
249 } | 268 } |
250 }; | 269 }; |
251 } | 270 } |
252 | 271 |
253 /** | 272 /** |
254 * @return whether the surface view is initialized and ready to render. | 273 * @return whether the surface view is initialized and ready to render. |
255 */ | 274 */ |
256 public boolean isInitialized() { | 275 public boolean isInitialized() { |
257 return mSurfaceView.getHolder().getSurface() != null; | 276 return mSurfaceView.getHolder().getSurface() != null; |
258 } | 277 } |
259 | 278 |
260 /** | 279 /** |
| 280 * Sets the VSyncListener to mVSync adapter to the provided listener from th
e |
| 281 * given ContentViewCore. |
| 282 * @param contentViewCore ContentViewCore instance go get the listener from. |
| 283 */ |
| 284 protected void setVSyncListener(ContentViewCore contentViewCore) { |
| 285 mVSyncAdapter.setVSyncListener(contentViewCore.getVSyncListener(mVSyncAd
apter)); |
| 286 } |
| 287 |
| 288 /** |
261 * Enter or leave overlay video mode. | 289 * Enter or leave overlay video mode. |
262 * @param enabled Whether overlay mode is enabled. | 290 * @param enabled Whether overlay mode is enabled. |
263 */ | 291 */ |
264 public void setOverlayVideoMode(boolean enabled) { | 292 public void setOverlayVideoMode(boolean enabled) { |
265 int format = enabled ? PixelFormat.TRANSLUCENT : PixelFormat.OPAQUE; | 293 int format = enabled ? PixelFormat.TRANSLUCENT : PixelFormat.OPAQUE; |
266 mSurfaceView.getHolder().setFormat(format); | 294 mSurfaceView.getHolder().setFormat(format); |
267 nativeSetOverlayVideoMode(mNativeContentViewRenderView, enabled); | 295 nativeSetOverlayVideoMode(mNativeContentViewRenderView, enabled); |
268 } | 296 } |
269 | 297 |
270 @CalledByNative | 298 @CalledByNative |
(...skipping 28 matching lines...) Expand all Loading... |
299 } | 327 } |
300 | 328 |
301 @CalledByNative | 329 @CalledByNative |
302 private void onSwapBuffersCompleted() { | 330 private void onSwapBuffersCompleted() { |
303 TraceEvent.instant("onSwapBuffersCompleted"); | 331 TraceEvent.instant("onSwapBuffersCompleted"); |
304 | 332 |
305 if (mPendingSwapBuffers == MAX_SWAP_BUFFER_COUNT && mNeedToRender) reque
stRender(); | 333 if (mPendingSwapBuffers == MAX_SWAP_BUFFER_COUNT && mNeedToRender) reque
stRender(); |
306 if (mPendingSwapBuffers > 0) mPendingSwapBuffers--; | 334 if (mPendingSwapBuffers > 0) mPendingSwapBuffers--; |
307 } | 335 } |
308 | 336 |
309 private void render() { | 337 /** |
| 338 * Calls Composite on the native side, finishing the compositing task for cu
rrent frame. |
| 339 */ |
| 340 protected void render() { |
310 if (mPendingRenders > 0) mPendingRenders--; | 341 if (mPendingRenders > 0) mPendingRenders--; |
311 | 342 |
312 // Waiting for the content view contents to be ready avoids compositing | 343 // Waiting for the content view contents to be ready avoids compositing |
313 // when the surface texture is still empty. | 344 // when the surface texture is still empty. |
314 if (mCurrentContentView == null) return; | 345 if (mCurrentContentView == null) return; |
315 ContentViewCore contentViewCore = mCurrentContentView.getContentViewCore
(); | 346 ContentViewCore contentViewCore = mCurrentContentView.getContentViewCore
(); |
316 if (contentViewCore == null || !contentViewCore.isReady()) { | 347 if (contentViewCore == null || !contentViewCore.isReady()) { |
317 return; | 348 return; |
318 } | 349 } |
319 | 350 |
320 boolean didDraw = nativeComposite(mNativeContentViewRenderView); | 351 boolean didDraw = nativeComposite(mNativeContentViewRenderView); |
321 if (didDraw) { | 352 if (didDraw) { |
322 mPendingSwapBuffers++; | 353 mPendingSwapBuffers++; |
323 if (mSurfaceView.getBackground() != null) { | 354 if (mSurfaceView.getBackground() != null) { |
324 post(new Runnable() { | 355 post(new Runnable() { |
325 @Override | 356 @Override |
326 public void run() { | 357 public void run() { |
327 mSurfaceView.setBackgroundResource(0); | 358 mSurfaceView.setBackgroundResource(0); |
328 } | 359 } |
329 }); | 360 }); |
330 } | 361 } |
331 } | 362 } |
332 } | 363 } |
333 | 364 |
334 private native long nativeInit(long rootWindowNativePointer); | 365 private native void nativeInit(long rootWindowNativePointer); |
335 private native void nativeDestroy(long nativeContentViewRenderView); | 366 private native void nativeDestroy(long nativeContentViewRenderView); |
336 private native void nativeSetCurrentContentView(long nativeContentViewRender
View, | 367 private native void nativeSetCurrentContentView(long nativeContentViewRender
View, |
337 long nativeContentView); | 368 long nativeContentView); |
338 private native void nativeSurfaceCreated(long nativeContentViewRenderView); | 369 private native void nativeSurfaceCreated(long nativeContentViewRenderView); |
339 private native void nativeSurfaceDestroyed(long nativeContentViewRenderView)
; | 370 private native void nativeSurfaceDestroyed(long nativeContentViewRenderView)
; |
340 private native void nativeSurfaceChanged(long nativeContentViewRenderView, | 371 private native void nativeSurfaceChanged(long nativeContentViewRenderView, |
341 int format, int width, int height, Surface surface); | 372 int format, int width, int height, Surface surface); |
342 private native boolean nativeComposite(long nativeContentViewRenderView); | 373 private native boolean nativeComposite(long nativeContentViewRenderView); |
343 private native boolean nativeCompositeToBitmap(long nativeContentViewRenderV
iew, Bitmap bitmap); | 374 private native boolean nativeCompositeToBitmap(long nativeContentViewRenderV
iew, Bitmap bitmap); |
344 private native void nativeSetOverlayVideoMode(long nativeContentViewRenderVi
ew, | 375 private native void nativeSetOverlayVideoMode(long nativeContentViewRenderVi
ew, |
345 boolean enabled); | 376 boolean enabled); |
346 } | 377 } |
OLD | NEW |