ContentViewRenderView.java revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1e62c1185bee05facc25d1d725434f517261d308bChris Lattner// Copyright 2012 The Chromium Authors. All rights reserved. 23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// Use of this source code is governed by a BSD-style license that can be 301d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell// found in the LICENSE file. 401d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell 53060910e290949a9ac5eda8726d030790c4d60ffChris Lattnerpackage org.chromium.content.browser; 63060910e290949a9ac5eda8726d030790c4d60ffChris Lattner 73da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukmanimport android.content.Context; 801d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswellimport android.graphics.Bitmap; 9e62c1185bee05facc25d1d725434f517261d308bChris Lattnerimport android.graphics.Canvas; 1014d7c59491347a2f8f29e120fd75a4cad42f68e7Chris Lattnerimport android.graphics.Color; 1114d7c59491347a2f8f29e120fd75a4cad42f68e7Chris Lattnerimport android.graphics.PixelFormat; 12e62c1185bee05facc25d1d725434f517261d308bChris Lattnerimport android.os.Build; 13e62c1185bee05facc25d1d725434f517261d308bChris Lattnerimport android.os.Handler; 14e62c1185bee05facc25d1d725434f517261d308bChris Lattnerimport android.view.Surface; 15e62c1185bee05facc25d1d725434f517261d308bChris Lattnerimport android.view.SurfaceHolder; 16e62c1185bee05facc25d1d725434f517261d308bChris Lattnerimport android.view.SurfaceView; 17e62c1185bee05facc25d1d725434f517261d308bChris Lattnerimport android.widget.FrameLayout; 18099e198ae84c1a6cfe2a7c79ee9f47fa67caac8fChris Lattner 193cc52ea33c0b96d1682f14fc45c45b57df0f39b6Michael J. Spencerimport org.chromium.base.CalledByNative; 201a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarimport org.chromium.base.JNINamespace; 21e62c1185bee05facc25d1d725434f517261d308bChris Lattnerimport org.chromium.base.ObserverList; 22028936ada14335bb04f377d46a6261dc4c66dafdJohn Criswellimport org.chromium.base.ObserverList.RewindableIterator; 23d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekeimport org.chromium.base.TraceEvent; 241a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarimport org.chromium.ui.base.WindowAndroid; 2521870411d9c1807526b613d04c2ebae5a43c263bBob Wilson 267dda395004eb962cef1c1554b1e8b2ad069760e0Chris Lattner/*** 277cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner * This view is used by a ContentView to render its content. 287cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner * Call {@link #setCurrentContentView(ContentView)} with the contentView that should be displayed. 297cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner * Note that only one ContentView can be shown at a time. 307cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner */ 317cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner@JNINamespace("content") 327cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattnerpublic class ContentViewRenderView extends FrameLayout { 3340f71134b9fef0ca06c516f033cc9403394a913cChris Lattner private static final int MAX_SWAP_BUFFER_COUNT = 2; 347cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner 357cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner // The native side of this object. 367dda395004eb962cef1c1554b1e8b2ad069760e0Chris Lattner private long mNativeContentViewRenderView; 371fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattner private final SurfaceHolder.Callback mSurfaceCallback; 38e62c1185bee05facc25d1d725434f517261d308bChris Lattner 39e62c1185bee05facc25d1d725434f517261d308bChris Lattner private final SurfaceView mSurfaceView; 40e62c1185bee05facc25d1d725434f517261d308bChris Lattner private final VSyncAdapter mVSyncAdapter; 41e62c1185bee05facc25d1d725434f517261d308bChris Lattner 42e62c1185bee05facc25d1d725434f517261d308bChris Lattner private int mPendingRenders; 43e3a1d054483d6e2551a43232f2c968fc7ce523f2Chris Lattner private int mPendingSwapBuffers; 44e62c1185bee05facc25d1d725434f517261d308bChris Lattner private boolean mNeedToRender; 45e6c27de069225e1122c78385ad22a2ff656db8e6David Greene 46711e5d96aa648ebe96b09483d0775f3b16283e3dChris Lattner private ContentView mCurrentContentView; 474afc509b7ffe2c4ea234dfd7af5105feb21685d9David Greene 48e62c1185bee05facc25d1d725434f517261d308bChris Lattner private final Runnable mRenderRunnable = new Runnable() { 498e9a9774eb12b5242f74b8ac5b20e0a938ec9c53Chris Lattner @Override 50b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner public void run() { 51b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner render(); 52a1651900e1772b05afd2280308e9acc5a58cefb8Chris Lattner } 53b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner }; 541dba7abdd77e19c230f0426825a5ae4879471dccChris Lattner 557cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner /** 567dda395004eb962cef1c1554b1e8b2ad069760e0Chris Lattner * Constructs a new ContentViewRenderView that should be can to a view hierarchy. 57e62c1185bee05facc25d1d725434f517261d308bChris Lattner * Native code should add/remove the layers to be rendered through the ContentViewLayerRenderer. 587dda395004eb962cef1c1554b1e8b2ad069760e0Chris Lattner * @param context The context used to create this. 59293b13350c2fbae8a64b0b0beb440cb859968c8cBob Wilson */ 60e62c1185bee05facc25d1d725434f517261d308bChris Lattner public ContentViewRenderView(Context context, WindowAndroid rootWindow) { 61e62c1185bee05facc25d1d725434f517261d308bChris Lattner super(context); 62e62c1185bee05facc25d1d725434f517261d308bChris Lattner assert rootWindow != null; 63e62c1185bee05facc25d1d725434f517261d308bChris Lattner mNativeContentViewRenderView = nativeInit(rootWindow.getNativePointer()); 64e62c1185bee05facc25d1d725434f517261d308bChris Lattner assert mNativeContentViewRenderView != 0; 65e62c1185bee05facc25d1d725434f517261d308bChris Lattner 66e62c1185bee05facc25d1d725434f517261d308bChris Lattner mSurfaceView = createSurfaceView(getContext()); 67e62c1185bee05facc25d1d725434f517261d308bChris Lattner mSurfaceView.setZOrderMediaOverlay(true); 6899ba1f7b8deaf2a296c98600dbf593754cbd43a2Chris Lattner mSurfaceCallback = new SurfaceHolder.Callback() { 691a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar @Override 707cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 717cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner assert mNativeContentViewRenderView != 0; 727cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner nativeSurfaceChanged(mNativeContentViewRenderView, 737cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner format, width, height, holder.getSurface()); 747cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner if (mCurrentContentView != null) { 757cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner mCurrentContentView.getContentViewCore().onPhysicalBackingSizeChanged( 767cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner width, height); 77e62c1185bee05facc25d1d725434f517261d308bChris Lattner } 78e62c1185bee05facc25d1d725434f517261d308bChris Lattner } 79e62c1185bee05facc25d1d725434f517261d308bChris Lattner 80e62c1185bee05facc25d1d725434f517261d308bChris Lattner @Override 81e62c1185bee05facc25d1d725434f517261d308bChris Lattner public void surfaceCreated(SurfaceHolder holder) { 82e62c1185bee05facc25d1d725434f517261d308bChris Lattner setSurfaceViewBackgroundColor(Color.WHITE); 83e6c27de069225e1122c78385ad22a2ff656db8e6David Greene 84e6c27de069225e1122c78385ad22a2ff656db8e6David Greene assert mNativeContentViewRenderView != 0; 85e6c27de069225e1122c78385ad22a2ff656db8e6David Greene nativeSurfaceCreated(mNativeContentViewRenderView); 86e8cf21e8e3db64dd49777d6bf6c867d47e9f5407David Greene 87e8cf21e8e3db64dd49777d6bf6c867d47e9f5407David Greene mPendingSwapBuffers = 0; 88e8cf21e8e3db64dd49777d6bf6c867d47e9f5407David Greene mPendingRenders = 0; 894afc509b7ffe2c4ea234dfd7af5105feb21685d9David Greene 904afc509b7ffe2c4ea234dfd7af5105feb21685d9David Greene onReadyToRender(); 914afc509b7ffe2c4ea234dfd7af5105feb21685d9David Greene } 92e3a1d054483d6e2551a43232f2c968fc7ce523f2Chris Lattner 93e62c1185bee05facc25d1d725434f517261d308bChris Lattner @Override 94e62c1185bee05facc25d1d725434f517261d308bChris Lattner public void surfaceDestroyed(SurfaceHolder holder) { 958e9a9774eb12b5242f74b8ac5b20e0a938ec9c53Chris Lattner assert mNativeContentViewRenderView != 0; 96b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner nativeSurfaceDestroyed(mNativeContentViewRenderView); 97b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner } 98b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner }; 99b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner mSurfaceView.getHolder().addCallback(mSurfaceCallback); 100b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner 101b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner mVSyncAdapter = new VSyncAdapter(getContext()); 102b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner addView(mSurfaceView, 103e62c1185bee05facc25d1d725434f517261d308bChris Lattner new FrameLayout.LayoutParams( 1047cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner FrameLayout.LayoutParams.MATCH_PARENT, 1057cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner FrameLayout.LayoutParams.MATCH_PARENT)); 1067cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner } 1077cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner 1087cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner private class VSyncAdapter implements VSyncManager.Provider, VSyncMonitor.Listener { 1097cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner private final VSyncMonitor mVSyncMonitor; 1107cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner private boolean mVSyncNotificationEnabled; 1117cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner private VSyncManager.Listener mVSyncListener; 1127cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner private final ObserverList<VSyncManager.Listener> mCurrentVSyncListeners; 11340f71134b9fef0ca06c516f033cc9403394a913cChris Lattner private final RewindableIterator<VSyncManager.Listener> mCurrentVSyncListenersIterator; 1147cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner 115e62c1185bee05facc25d1d725434f517261d308bChris Lattner // The VSyncMonitor gives the timebase for the actual vsync, but we don't want render until 116e62c1185bee05facc25d1d725434f517261d308bChris Lattner // we have had a chance for input events to propagate to the compositor thread. This takes 1171a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar // 3 ms typically, so we adjust the vsync timestamps forward by a bit to give input events a 118e62c1185bee05facc25d1d725434f517261d308bChris Lattner // chance to arrive. 119e62c1185bee05facc25d1d725434f517261d308bChris Lattner private static final long INPUT_EVENT_LAG_FROM_VSYNC_MICROSECONDS = 3200; 120e62c1185bee05facc25d1d725434f517261d308bChris Lattner 121e62c1185bee05facc25d1d725434f517261d308bChris Lattner VSyncAdapter(Context context) { 12207278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner mVSyncMonitor = new VSyncMonitor(context, this); 12307278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner mCurrentVSyncListeners = new ObserverList<VSyncManager.Listener>(); 12407278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner mCurrentVSyncListenersIterator = mCurrentVSyncListeners.rewindableIterator(); 1251fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattner } 1261fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattner 127ead87b671278379f92890fddd859a301bb68f462Reid Spencer @Override 128ead87b671278379f92890fddd859a301bb68f462Reid Spencer public void onVSync(VSyncMonitor monitor, long vsyncTimeMicros) { 129ead87b671278379f92890fddd859a301bb68f462Reid Spencer if (mNeedToRender) { 130ead87b671278379f92890fddd859a301bb68f462Reid Spencer if (mPendingSwapBuffers + mPendingRenders <= MAX_SWAP_BUFFER_COUNT) { 131ead87b671278379f92890fddd859a301bb68f462Reid Spencer mNeedToRender = false; 132ead87b671278379f92890fddd859a301bb68f462Reid Spencer mPendingRenders++; 133ead87b671278379f92890fddd859a301bb68f462Reid Spencer render(); 134ead87b671278379f92890fddd859a301bb68f462Reid Spencer } else { 135ead87b671278379f92890fddd859a301bb68f462Reid Spencer TraceEvent.instant("ContentViewRenderView:bail"); 136ead87b671278379f92890fddd859a301bb68f462Reid Spencer } 137e6c27de069225e1122c78385ad22a2ff656db8e6David Greene } 138e8cf21e8e3db64dd49777d6bf6c867d47e9f5407David Greene 1394afc509b7ffe2c4ea234dfd7af5105feb21685d9David Greene if (mVSyncListener != null) { 140ead87b671278379f92890fddd859a301bb68f462Reid Spencer if (mVSyncNotificationEnabled) { 141ead87b671278379f92890fddd859a301bb68f462Reid Spencer for (mCurrentVSyncListenersIterator.rewind(); 142ead87b671278379f92890fddd859a301bb68f462Reid Spencer mCurrentVSyncListenersIterator.hasNext();) { 143e62c1185bee05facc25d1d725434f517261d308bChris Lattner mCurrentVSyncListenersIterator.next().onVSync(vsyncTimeMicros); 14499ba1f7b8deaf2a296c98600dbf593754cbd43a2Chris Lattner } 1457cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner mVSyncMonitor.requestUpdate(); 1467cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner } else { 1477cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner // Compensate for input event lag. Input events are delivered immediately on 1487cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner // pre-JB releases, so this adjustment is only done for later versions. 149ead87b671278379f92890fddd859a301bb68f462Reid Spencer if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 150ead87b671278379f92890fddd859a301bb68f462Reid Spencer vsyncTimeMicros += INPUT_EVENT_LAG_FROM_VSYNC_MICROSECONDS; 151ead87b671278379f92890fddd859a301bb68f462Reid Spencer } 152ead87b671278379f92890fddd859a301bb68f462Reid Spencer mVSyncListener.updateVSync(vsyncTimeMicros, 153ead87b671278379f92890fddd859a301bb68f462Reid Spencer mVSyncMonitor.getVSyncPeriodInMicroseconds()); 154ead87b671278379f92890fddd859a301bb68f462Reid Spencer } 155ead87b671278379f92890fddd859a301bb68f462Reid Spencer } 156ead87b671278379f92890fddd859a301bb68f462Reid Spencer } 157ead87b671278379f92890fddd859a301bb68f462Reid Spencer 158e62c1185bee05facc25d1d725434f517261d308bChris Lattner @Override 159e62c1185bee05facc25d1d725434f517261d308bChris Lattner public void registerVSyncListener(VSyncManager.Listener listener) { 16007278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner if (!mVSyncNotificationEnabled) mVSyncMonitor.requestUpdate(); 161234b3ec8795e0661af56aa1d1a978a41d80686c5Misha Brukman mCurrentVSyncListeners.addObserver(listener); 162234b3ec8795e0661af56aa1d1a978a41d80686c5Misha Brukman mVSyncNotificationEnabled = true; 16307278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner } 164e62c1185bee05facc25d1d725434f517261d308bChris Lattner 165e62c1185bee05facc25d1d725434f517261d308bChris Lattner @Override 166e62c1185bee05facc25d1d725434f517261d308bChris Lattner public void unregisterVSyncListener(VSyncManager.Listener listener) { 1671002c0203450620594a85454c6a095ca94b87cb2Dan Gohman mCurrentVSyncListeners.removeObserver(listener); 168e62c1185bee05facc25d1d725434f517261d308bChris Lattner mCurrentVSyncListenersIterator.rewind(); 169e62c1185bee05facc25d1d725434f517261d308bChris Lattner if (!mCurrentVSyncListenersIterator.hasNext()) { 170e62c1185bee05facc25d1d725434f517261d308bChris Lattner mVSyncNotificationEnabled = false; 171ead87b671278379f92890fddd859a301bb68f462Reid Spencer } 172ead87b671278379f92890fddd859a301bb68f462Reid Spencer } 173ead87b671278379f92890fddd859a301bb68f462Reid Spencer 174ead87b671278379f92890fddd859a301bb68f462Reid Spencer void setVSyncListener(VSyncManager.Listener listener) { 175ead87b671278379f92890fddd859a301bb68f462Reid Spencer mVSyncListener = listener; 176ead87b671278379f92890fddd859a301bb68f462Reid Spencer if (mVSyncListener != null) mVSyncMonitor.requestUpdate(); 177ead87b671278379f92890fddd859a301bb68f462Reid Spencer } 178ead87b671278379f92890fddd859a301bb68f462Reid Spencer 179ead87b671278379f92890fddd859a301bb68f462Reid Spencer void requestUpdate() { 180ead87b671278379f92890fddd859a301bb68f462Reid Spencer mVSyncMonitor.requestUpdate(); 181e6c27de069225e1122c78385ad22a2ff656db8e6David Greene } 182e8cf21e8e3db64dd49777d6bf6c867d47e9f5407David Greene } 1834afc509b7ffe2c4ea234dfd7af5105feb21685d9David Greene 184ead87b671278379f92890fddd859a301bb68f462Reid Spencer /** 185ead87b671278379f92890fddd859a301bb68f462Reid Spencer * Sets the background color of the surface view. This method is necessary because the 186ead87b671278379f92890fddd859a301bb68f462Reid Spencer * background color of ContentViewRenderView itself is covered by the background of 187ead87b671278379f92890fddd859a301bb68f462Reid Spencer * SurfaceView. 18899ba1f7b8deaf2a296c98600dbf593754cbd43a2Chris Lattner * @param color The color of the background. 1897cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner */ 1907cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner public void setSurfaceViewBackgroundColor(int color) { 1917cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner if (mSurfaceView != null) { 1927cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner mSurfaceView.setBackgroundColor(color); 193ead87b671278379f92890fddd859a301bb68f462Reid Spencer } 194ead87b671278379f92890fddd859a301bb68f462Reid Spencer } 1957cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner 1967cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner /** 197ead87b671278379f92890fddd859a301bb68f462Reid Spencer * Should be called when the ContentViewRenderView is not needed anymore so its associated 198ead87b671278379f92890fddd859a301bb68f462Reid Spencer * native resource can be freed. 199ead87b671278379f92890fddd859a301bb68f462Reid Spencer */ 200ead87b671278379f92890fddd859a301bb68f462Reid Spencer public void destroy() { 201ead87b671278379f92890fddd859a301bb68f462Reid Spencer mSurfaceView.getHolder().removeCallback(mSurfaceCallback); 202ead87b671278379f92890fddd859a301bb68f462Reid Spencer nativeDestroy(mNativeContentViewRenderView); 203ead87b671278379f92890fddd859a301bb68f462Reid Spencer mNativeContentViewRenderView = 0; 204e62c1185bee05facc25d1d725434f517261d308bChris Lattner } 205e62c1185bee05facc25d1d725434f517261d308bChris Lattner 20607278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner /** 20707278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner * Makes the passed ContentView the one displayed by this ContentViewRenderView. 20807278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner */ 2091fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattner public void setCurrentContentView(ContentView contentView) { 2101fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattner assert mNativeContentViewRenderView != 0; 211ead87b671278379f92890fddd859a301bb68f462Reid Spencer mCurrentContentView = contentView; 212ead87b671278379f92890fddd859a301bb68f462Reid Spencer 213ead87b671278379f92890fddd859a301bb68f462Reid Spencer ContentViewCore contentViewCore = 214ead87b671278379f92890fddd859a301bb68f462Reid Spencer contentView != null ? contentView.getContentViewCore() : null; 215ead87b671278379f92890fddd859a301bb68f462Reid Spencer 216ead87b671278379f92890fddd859a301bb68f462Reid Spencer nativeSetCurrentContentView(mNativeContentViewRenderView, 217ead87b671278379f92890fddd859a301bb68f462Reid Spencer contentViewCore != null ? contentViewCore.getNativeContentViewCore() : 0); 218ead87b671278379f92890fddd859a301bb68f462Reid Spencer 219ead87b671278379f92890fddd859a301bb68f462Reid Spencer if (contentViewCore != null) { 220ead87b671278379f92890fddd859a301bb68f462Reid Spencer contentViewCore.onPhysicalBackingSizeChanged(getWidth(), getHeight()); 221e6c27de069225e1122c78385ad22a2ff656db8e6David Greene mVSyncAdapter.setVSyncListener(contentViewCore.getVSyncListener(mVSyncAdapter)); 222e8cf21e8e3db64dd49777d6bf6c867d47e9f5407David Greene } 2234afc509b7ffe2c4ea234dfd7af5105feb21685d9David Greene } 224ead87b671278379f92890fddd859a301bb68f462Reid Spencer 225ead87b671278379f92890fddd859a301bb68f462Reid Spencer /** 226ead87b671278379f92890fddd859a301bb68f462Reid Spencer * This method should be subclassed to provide actions to be performed once the view is ready to 227ead87b671278379f92890fddd859a301bb68f462Reid Spencer * render. 22899ba1f7b8deaf2a296c98600dbf593754cbd43a2Chris Lattner */ 2297cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner protected void onReadyToRender() { 2307cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner } 2317cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner 2327cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner /** 2337cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner * This method could be subclassed optionally to provide a custom SurfaceView object to 234ead87b671278379f92890fddd859a301bb68f462Reid Spencer * this ContentViewRenderView. 235ead87b671278379f92890fddd859a301bb68f462Reid Spencer * @param context The context used to create the SurfaceView object. 236ead87b671278379f92890fddd859a301bb68f462Reid Spencer * @return The created SurfaceView object. 237ead87b671278379f92890fddd859a301bb68f462Reid Spencer */ 238ead87b671278379f92890fddd859a301bb68f462Reid Spencer protected SurfaceView createSurfaceView(Context context) { 239ead87b671278379f92890fddd859a301bb68f462Reid Spencer return new SurfaceView(context) { 240ead87b671278379f92890fddd859a301bb68f462Reid Spencer @Override 241ead87b671278379f92890fddd859a301bb68f462Reid Spencer public void onDraw(Canvas canvas) { 242ead87b671278379f92890fddd859a301bb68f462Reid Spencer // We only need to draw to software canvases, which are used for taking screenshots. 243e62c1185bee05facc25d1d725434f517261d308bChris Lattner if (canvas.isHardwareAccelerated()) return; 244e62c1185bee05facc25d1d725434f517261d308bChris Lattner Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), 24507278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner Bitmap.Config.ARGB_8888); 24607278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner if (nativeCompositeToBitmap(mNativeContentViewRenderView, bitmap)) { 2471fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattner canvas.drawBitmap(bitmap, 0, 0, null); 2481fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattner } 249ead87b671278379f92890fddd859a301bb68f462Reid Spencer } 250ead87b671278379f92890fddd859a301bb68f462Reid Spencer }; 251ead87b671278379f92890fddd859a301bb68f462Reid Spencer } 252ead87b671278379f92890fddd859a301bb68f462Reid Spencer 253ead87b671278379f92890fddd859a301bb68f462Reid Spencer /** 254ead87b671278379f92890fddd859a301bb68f462Reid Spencer * @return whether the surface view is initialized and ready to render. 255e6c27de069225e1122c78385ad22a2ff656db8e6David Greene */ 256711e5d96aa648ebe96b09483d0775f3b16283e3dChris Lattner public boolean isInitialized() { 2574afc509b7ffe2c4ea234dfd7af5105feb21685d9David Greene return mSurfaceView.getHolder().getSurface() != null; 258d418c1b768b5ff26afe05a5ce84d920bbbc99583David Greene } 259ead87b671278379f92890fddd859a301bb68f462Reid Spencer 260ead87b671278379f92890fddd859a301bb68f462Reid Spencer /** 261ead87b671278379f92890fddd859a301bb68f462Reid Spencer * Enter or leave overlay video mode. 262ead87b671278379f92890fddd859a301bb68f462Reid Spencer * @param enabled Whether overlay mode is enabled. 263ead87b671278379f92890fddd859a301bb68f462Reid Spencer */ 264ead87b671278379f92890fddd859a301bb68f462Reid Spencer public void setOverlayVideoMode(boolean enabled) { 265ead87b671278379f92890fddd859a301bb68f462Reid Spencer int format = enabled ? PixelFormat.TRANSLUCENT : PixelFormat.OPAQUE; 266ead87b671278379f92890fddd859a301bb68f462Reid Spencer mSurfaceView.getHolder().setFormat(format); 26799ba1f7b8deaf2a296c98600dbf593754cbd43a2Chris Lattner nativeSetOverlayVideoMode(mNativeContentViewRenderView, enabled); 2687cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner } 2697cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner 2707cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner @CalledByNative 2717cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner private void requestRender() { 2727cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner ContentViewCore contentViewCore = mCurrentContentView != null ? 273ead87b671278379f92890fddd859a301bb68f462Reid Spencer mCurrentContentView.getContentViewCore() : null; 274ead87b671278379f92890fddd859a301bb68f462Reid Spencer 275ead87b671278379f92890fddd859a301bb68f462Reid Spencer boolean rendererHasFrame = 2767cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner contentViewCore != null && contentViewCore.consumePendingRendererFrame(); 277ead87b671278379f92890fddd859a301bb68f462Reid Spencer 278ead87b671278379f92890fddd859a301bb68f462Reid Spencer if (rendererHasFrame && mPendingSwapBuffers + mPendingRenders < MAX_SWAP_BUFFER_COUNT) { 279ead87b671278379f92890fddd859a301bb68f462Reid Spencer TraceEvent.instant("requestRender:now"); 280ead87b671278379f92890fddd859a301bb68f462Reid Spencer mNeedToRender = false; 281e62c1185bee05facc25d1d725434f517261d308bChris Lattner mPendingRenders++; 282e62c1185bee05facc25d1d725434f517261d308bChris Lattner 283234b3ec8795e0661af56aa1d1a978a41d80686c5Misha Brukman // The handler can be null if we are detached from the window. Calling 284234b3ec8795e0661af56aa1d1a978a41d80686c5Misha Brukman // {@link View#post(Runnable)} properly handles this case, but we lose the front of 285234b3ec8795e0661af56aa1d1a978a41d80686c5Misha Brukman // queue behavior. That is okay for this edge case. 286234b3ec8795e0661af56aa1d1a978a41d80686c5Misha Brukman Handler handler = getHandler(); 28707278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner if (handler != null) { 288e62c1185bee05facc25d1d725434f517261d308bChris Lattner handler.postAtFrontOfQueue(mRenderRunnable); 2897cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner } else { 290e62c1185bee05facc25d1d725434f517261d308bChris Lattner post(mRenderRunnable); 2911002c0203450620594a85454c6a095ca94b87cb2Dan Gohman } 292f1b36f9a71eb267f04b7bd3a32aca9bc69f71e97Chris Lattner mVSyncAdapter.requestUpdate(); 2937cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner } else if (mPendingRenders <= 0) { 294f1b36f9a71eb267f04b7bd3a32aca9bc69f71e97Chris Lattner assert mPendingRenders == 0; 295ead87b671278379f92890fddd859a301bb68f462Reid Spencer TraceEvent.instant("requestRender:later"); 296ead87b671278379f92890fddd859a301bb68f462Reid Spencer mNeedToRender = true; 297ead87b671278379f92890fddd859a301bb68f462Reid Spencer mVSyncAdapter.requestUpdate(); 298ead87b671278379f92890fddd859a301bb68f462Reid Spencer } 299ead87b671278379f92890fddd859a301bb68f462Reid Spencer } 300ead87b671278379f92890fddd859a301bb68f462Reid Spencer 301ead87b671278379f92890fddd859a301bb68f462Reid Spencer @CalledByNative 302ead87b671278379f92890fddd859a301bb68f462Reid Spencer private void onSwapBuffersCompleted() { 303ead87b671278379f92890fddd859a301bb68f462Reid Spencer TraceEvent.instant("onSwapBuffersCompleted"); 304ead87b671278379f92890fddd859a301bb68f462Reid Spencer 305e6c27de069225e1122c78385ad22a2ff656db8e6David Greene if (mPendingSwapBuffers == MAX_SWAP_BUFFER_COUNT && mNeedToRender) requestRender(); 306e8cf21e8e3db64dd49777d6bf6c867d47e9f5407David Greene if (mPendingSwapBuffers > 0) mPendingSwapBuffers--; 3074afc509b7ffe2c4ea234dfd7af5105feb21685d9David Greene } 308ead87b671278379f92890fddd859a301bb68f462Reid Spencer 309ead87b671278379f92890fddd859a301bb68f462Reid Spencer private void render() { 310ead87b671278379f92890fddd859a301bb68f462Reid Spencer if (mPendingRenders > 0) mPendingRenders--; 3113da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 31299ba1f7b8deaf2a296c98600dbf593754cbd43a2Chris Lattner // Waiting for the content view contents to be ready avoids compositing 3137cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner // when the surface texture is still empty. 3147cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner if (mCurrentContentView == null) return; 3157cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner ContentViewCore contentViewCore = mCurrentContentView.getContentViewCore(); 3167cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner if (contentViewCore == null || !contentViewCore.isReady()) { 3177cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner return; 318ead87b671278379f92890fddd859a301bb68f462Reid Spencer } 319ead87b671278379f92890fddd859a301bb68f462Reid Spencer 320ead87b671278379f92890fddd859a301bb68f462Reid Spencer boolean didDraw = nativeComposite(mNativeContentViewRenderView); 321ead87b671278379f92890fddd859a301bb68f462Reid Spencer if (didDraw) { 322ead87b671278379f92890fddd859a301bb68f462Reid Spencer mPendingSwapBuffers++; 3233da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman if (mSurfaceView.getBackground() != null) { 3247cf0ce4b8d122575c3348b5fa4947014c3d8432dChris Lattner post(new Runnable() { 325ead87b671278379f92890fddd859a301bb68f462Reid Spencer @Override 326ead87b671278379f92890fddd859a301bb68f462Reid Spencer public void run() { 327ead87b671278379f92890fddd859a301bb68f462Reid Spencer mSurfaceView.setBackgroundResource(0); 328e62c1185bee05facc25d1d725434f517261d308bChris Lattner } 329e62c1185bee05facc25d1d725434f517261d308bChris Lattner }); 330f05760de76b4ec26474da18c97770ca369972cfdChris Lattner } 331f05760de76b4ec26474da18c97770ca369972cfdChris Lattner } 3321fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattner } 3331fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattner 334ead87b671278379f92890fddd859a301bb68f462Reid Spencer private native long nativeInit(long rootWindowNativePointer); 335ead87b671278379f92890fddd859a301bb68f462Reid Spencer private native void nativeDestroy(long nativeContentViewRenderView); 336ead87b671278379f92890fddd859a301bb68f462Reid Spencer private native void nativeSetCurrentContentView(long nativeContentViewRenderView, 337ead87b671278379f92890fddd859a301bb68f462Reid Spencer long nativeContentView); 338ead87b671278379f92890fddd859a301bb68f462Reid Spencer private native void nativeSurfaceCreated(long nativeContentViewRenderView); 339ead87b671278379f92890fddd859a301bb68f462Reid Spencer private native void nativeSurfaceDestroyed(long nativeContentViewRenderView); 340ead87b671278379f92890fddd859a301bb68f462Reid Spencer private native void nativeSurfaceChanged(long nativeContentViewRenderView, 341ead87b671278379f92890fddd859a301bb68f462Reid Spencer int format, int width, int height, Surface surface); 342ead87b671278379f92890fddd859a301bb68f462Reid Spencer private native boolean nativeComposite(long nativeContentViewRenderView); 343ead87b671278379f92890fddd859a301bb68f462Reid Spencer private native boolean nativeCompositeToBitmap(long nativeContentViewRenderView, Bitmap bitmap); 344e6c27de069225e1122c78385ad22a2ff656db8e6David Greene private native void nativeSetOverlayVideoMode(long nativeContentViewRenderView, 345e8cf21e8e3db64dd49777d6bf6c867d47e9f5407David Greene boolean enabled); 3464afc509b7ffe2c4ea234dfd7af5105feb21685d9David Greene} 347ead87b671278379f92890fddd859a301bb68f462Reid Spencer