| 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 |