Chromium Code Reviews| Index: chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java |
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java |
| index 9daf04df401994495933609689b3e0cfba589028..386e2d335451fd28478e5b4e309cf3a2bf0ee0c9 100644 |
| --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java |
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java |
| @@ -13,6 +13,7 @@ import static android.opengl.GLES20.glTexParameteri; |
| import android.annotation.SuppressLint; |
| import android.app.Activity; |
| +import android.graphics.Point; |
| import android.graphics.SurfaceTexture; |
| import android.graphics.SurfaceTexture.OnFrameAvailableListener; |
| import android.opengl.GLES11Ext; |
| @@ -29,6 +30,7 @@ import com.google.vr.ndk.base.GvrLayout; |
| import org.chromium.base.CommandLine; |
| import org.chromium.base.ThreadUtils; |
| +import org.chromium.base.annotations.CalledByNative; |
| import org.chromium.base.annotations.JNINamespace; |
| import org.chromium.chrome.browser.ChromeSwitches; |
| import org.chromium.chrome.browser.ChromeVersionInfo; |
| @@ -40,6 +42,8 @@ import org.chromium.content.browser.ContentViewCore; |
| import org.chromium.content_public.browser.WebContents; |
| import org.chromium.ui.base.ViewAndroidDelegate; |
| import org.chromium.ui.base.WindowAndroid; |
| +import org.chromium.ui.display.DisplayAndroid; |
| +import org.chromium.ui.display.VirtualDisplayAndroid; |
| import javax.microedition.khronos.egl.EGLConfig; |
| import javax.microedition.khronos.opengles.GL10; |
| @@ -51,9 +55,24 @@ import javax.microedition.khronos.opengles.GL10; |
| public class VrShellImpl extends GvrLayout implements GLSurfaceView.Renderer, VrShell { |
| private static final String TAG = "VrShellImpl"; |
| - private Activity mActivity; |
| + // TODO(mthiesse): These values work well for Pixel/Pixel XL in VR, but we need to come up with |
| + // a way to compute good values for any screen size/scaling ratio. |
| + |
| + // Increasing DPR any more than this doesn't appear to increase text quality. |
| + private static final float DEFAULT_DPR = 1.2f; |
| + // Fairly arbitrary values that put a good amount of content on the screen without making the |
| + // text too small to read. |
| + private static final float DEFAULT_CONTENT_WIDTH = 1024f; |
| + private static final float DEFAULT_CONTENT_HEIGHT = 576f; |
| + // Temporary values that will be changed when the UI loads and figures out how what size it |
| + // needs to be. |
| + private static final float DEFAULT_UI_WIDTH = 1920f; |
| + private static final float DEFAULT_UI_HEIGHT = 1080f; |
| private final GLSurfaceView mGlSurfaceView; |
| + private final Activity mActivity; |
| + private final VirtualDisplayAndroid mContentVirtualDisplay; |
| + private final VirtualDisplayAndroid mUiVirtualDisplay; |
| private long mNativeVrShell = 0; |
| @@ -62,7 +81,8 @@ public class VrShellImpl extends GvrLayout implements GLSurfaceView.Renderer, Vr |
| private FrameListener mContentFrameListener; |
| private FrameListener mUiFrameListener; |
| - private FrameLayout mContentViewCoreContainer; |
| + private FrameLayout mContentCVCContainer; |
| + private FrameLayout mUiCVCContainer; |
| // The tab that holds the main ContentViewCore. |
| private Tab mTab; |
| @@ -83,18 +103,30 @@ public class VrShellImpl extends GvrLayout implements GLSurfaceView.Renderer, Vr |
| private ContentViewCore mUiCVC; |
| private VrWindowAndroid mUiVrWindowAndroid; |
| + private boolean mSurfacesInitialized; |
| + private int mContentSurfaceWidth = -1; |
| + private int mContentSurfaceHeight = -1; |
| + private int mUiSurfaceWidth = -1; |
| + private int mUiSurfaceHeight = -1; |
| + |
| public VrShellImpl(Activity activity) { |
| super(activity); |
| mActivity = activity; |
| - mContentViewCoreContainer = new FrameLayout(getContext()) { |
| + mContentCVCContainer = new FrameLayout(getContext()) { |
| @Override |
| public boolean dispatchTouchEvent(MotionEvent event) { |
| return true; |
| } |
| }; |
| - addView(mContentViewCoreContainer, 0, new FrameLayout.LayoutParams( |
| - FrameLayout.LayoutParams.MATCH_PARENT, |
| - FrameLayout.LayoutParams.MATCH_PARENT)); |
| + mUiCVCContainer = new FrameLayout(getContext()) { |
| + @Override |
| + public boolean dispatchTouchEvent(MotionEvent event) { |
| + return true; |
| + } |
| + }; |
| + addView(mContentCVCContainer, 0, new FrameLayout.LayoutParams(0, 0)); |
| + addView(mUiCVCContainer, 0, new FrameLayout.LayoutParams(0, 0)); |
| + |
| mGlSurfaceView = new GLSurfaceView(getContext()); |
| mGlSurfaceView.setEGLContextClientVersion(2); |
| mGlSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 0, 0); |
| @@ -105,6 +137,11 @@ public class VrShellImpl extends GvrLayout implements GLSurfaceView.Renderer, Vr |
| if (setAsyncReprojectionEnabled(true)) { |
| AndroidCompat.setSustainedPerformanceMode(mActivity, true); |
| } |
| + DisplayAndroid primaryDisplay = DisplayAndroid.getNonMultiDisplay(activity); |
| + mContentVirtualDisplay = VirtualDisplayAndroid.createVirtualDisplay(); |
| + mContentVirtualDisplay.setTo(primaryDisplay); |
| + mUiVirtualDisplay = VirtualDisplayAndroid.createVirtualDisplay(); |
| + mUiVirtualDisplay.setTo(primaryDisplay); |
| } |
| @Override |
| @@ -112,18 +149,37 @@ public class VrShellImpl extends GvrLayout implements GLSurfaceView.Renderer, Vr |
| assert currentTab.getContentViewCore() != null; |
| mTab = currentTab; |
| mContentCVC = mTab.getContentViewCore(); |
| - mContentVrWindowAndroid = new VrWindowAndroid(mActivity); |
| + mContentVrWindowAndroid = new VrWindowAndroid(mActivity, mContentVirtualDisplay); |
| - mUiVrWindowAndroid = new VrWindowAndroid(mActivity); |
| + mUiVrWindowAndroid = new VrWindowAndroid(mActivity, mUiVirtualDisplay); |
| mUiContents = WebContentsFactory.createWebContents(true, false); |
| mUiCVC = new ContentViewCore(mActivity, ChromeVersionInfo.getProductVersion()); |
| ContentView uiContentView = ContentView.createContentView(mActivity, mUiCVC); |
| mUiCVC.initialize(ViewAndroidDelegate.createBasicDelegate(uiContentView), |
| uiContentView, mUiContents, mUiVrWindowAndroid); |
| + // Set the UI and content sizes before we initialize VR Shell and load the UI. |
| + setUiCssSize(DEFAULT_UI_WIDTH, DEFAULT_UI_HEIGHT, DEFAULT_DPR); |
|
bshe
2016/11/30 23:00:46
can line 161 -172 moved after we create mNativeVrS
mthiesse
2016/11/30 23:25:05
If you'd like I can split up initialization into m
|
| + float dpr; |
| + if (forWebVR) { |
| + DisplayAndroid primaryDisplay = DisplayAndroid.getNonMultiDisplay(mActivity); |
| + dpr = 1f; |
|
bshe
2016/11/30 23:00:46
nit: avoid magic number
mthiesse
2016/11/30 23:25:05
Done.
|
| + setContentCssSize(primaryDisplay.getPhysicalDisplayWidth(), |
| + primaryDisplay.getPhysicalDisplayHeight(), dpr); |
| + } else { |
| + dpr = DEFAULT_DPR; |
| + setContentCssSize(DEFAULT_CONTENT_WIDTH, DEFAULT_CONTENT_HEIGHT, dpr); |
| + } |
| + |
| mNativeVrShell = nativeInit(mContentCVC.getWebContents(), |
| mContentVrWindowAndroid.getNativePointer(), mUiContents, |
| mUiVrWindowAndroid.getNativePointer(), forWebVR); |
| + |
| + // Set the initial Content and UI bounds, as they won't have been propagated yet. |
| + nativeContentBoundsChanged(mNativeVrShell, mContentSurfaceWidth, mContentSurfaceHeight, |
| + dpr); |
| + nativeUIBoundsChanged(mNativeVrShell, mUiSurfaceWidth, mUiSurfaceHeight, 1f); |
|
bshe
2016/11/30 23:00:46
ditto
mthiesse
2016/11/30 23:25:05
Good catch, that was a typo.
|
| + |
| mGlSurfaceView.setOnTouchListener(new View.OnTouchListener() { |
| @Override |
| @SuppressLint("ClickableViewAccessibility") |
| @@ -139,7 +195,7 @@ public class VrShellImpl extends GvrLayout implements GLSurfaceView.Renderer, Vr |
| uiContentView.setVisibility(View.VISIBLE); |
| mUiCVC.onShow(); |
| - mContentViewCoreContainer.addView(uiContentView, new FrameLayout.LayoutParams( |
| + mUiCVCContainer.addView(uiContentView, new FrameLayout.LayoutParams( |
| FrameLayout.LayoutParams.MATCH_PARENT, |
| FrameLayout.LayoutParams.MATCH_PARENT)); |
| mUiCVC.setBottomControlsHeight(0); |
| @@ -164,7 +220,7 @@ public class VrShellImpl extends GvrLayout implements GLSurfaceView.Renderer, Vr |
| mOriginalLayoutParams = mTabParent.getLayoutParams(); |
| mTabParentParent.removeView(mTabParent); |
| - mContentViewCoreContainer.addView(mTabParent, new FrameLayout.LayoutParams( |
| + mContentCVCContainer.addView(mTabParent, new FrameLayout.LayoutParams( |
| FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)); |
| } |
| @@ -173,13 +229,68 @@ public class VrShellImpl extends GvrLayout implements GLSurfaceView.Renderer, Vr |
| // If the tab's view has changed, the necessary view reparenting has already been done. |
| if (mTab.getView() == mTabParent) { |
| - mContentViewCoreContainer.removeView(mTabParent); |
| + mContentCVCContainer.removeView(mTabParent); |
| mTabParentParent.addView(mTabParent, mOriginalTabParentIndex, mOriginalLayoutParams); |
| mTabParent.requestFocus(); |
| } |
| mTabParent = null; |
| } |
| + private final Runnable mUpdateContentBufferSize = new Runnable() { |
| + @Override |
| + public void run() { |
| + if (mSurfacesInitialized) { |
| + mContentFrameListener.mSurfaceTexture.setDefaultBufferSize( |
| + mContentSurfaceWidth, mContentSurfaceHeight); |
| + } |
| + } |
| + }; |
| + |
| + private final Runnable mUpdateUiBufferSize = new Runnable() { |
| + @Override |
| + public void run() { |
| + if (mSurfacesInitialized) { |
| + mUiFrameListener.mSurfaceTexture.setDefaultBufferSize( |
| + mUiSurfaceWidth, mUiSurfaceHeight); |
| + } |
| + } |
| + }; |
| + |
| + @CalledByNative |
| + public void setUiCssSize(float width, float height, float dpr) { |
| + ThreadUtils.assertOnUiThread(); |
| + mUiSurfaceWidth = (int) Math.ceil(width * dpr); |
| + mUiSurfaceHeight = (int) Math.ceil(height * dpr); |
| + |
| + Point size = new Point(mUiSurfaceWidth, mUiSurfaceHeight); |
| + mUiVirtualDisplay.update(size, size, dpr, null, null, null); |
| + |
| + mGlSurfaceView.post(mUpdateUiBufferSize); |
| + mUiCVCContainer.setLayoutParams(new FrameLayout.LayoutParams( |
| + mUiSurfaceWidth, mUiSurfaceHeight)); |
| + mUiCVC.onPhysicalBackingSizeChanged(mUiSurfaceWidth, mUiSurfaceHeight); |
| + if (mNativeVrShell == 0) return; |
| + nativeUIBoundsChanged(mNativeVrShell, mUiSurfaceWidth, mUiSurfaceHeight, dpr); |
| + } |
| + |
| + @CalledByNative |
| + public void setContentCssSize(float width, float height, float dpr) { |
| + ThreadUtils.assertOnUiThread(); |
| + mContentSurfaceWidth = (int) Math.ceil(width * dpr); |
| + mContentSurfaceHeight = (int) Math.ceil(height * dpr); |
| + |
| + Point size = new Point(mContentSurfaceWidth, mContentSurfaceHeight); |
| + mContentVirtualDisplay.update(size, size, dpr, null, null, null); |
| + |
| + mGlSurfaceView.post(mUpdateContentBufferSize); |
| + mContentCVCContainer.setLayoutParams(new FrameLayout.LayoutParams( |
| + mContentSurfaceWidth, mContentSurfaceHeight)); |
| + mContentCVC.onPhysicalBackingSizeChanged(mContentSurfaceWidth, mContentSurfaceHeight); |
| + if (mNativeVrShell == 0) return; |
| + nativeContentBoundsChanged(mNativeVrShell, mContentSurfaceWidth, mContentSurfaceHeight, |
| + dpr); |
| + } |
| + |
| private static class FrameListener implements OnFrameAvailableListener { |
| final SurfaceTexture mSurfaceTexture; |
| final GLSurfaceView mGlSurfaceView; |
| @@ -210,26 +321,28 @@ public class VrShellImpl extends GvrLayout implements GLSurfaceView.Renderer, Vr |
| @Override |
| public void onSurfaceCreated(GL10 gl, EGLConfig config) { |
| - final int width = mContentCVC.getContainerView().getWidth(); |
| - final int height = mContentCVC.getContainerView().getHeight(); |
| mContentTextureHandle = createExternalTextureHandle(); |
| mUiTextureHandle = createExternalTextureHandle(); |
| mContentFrameListener = new FrameListener(mContentTextureHandle, mGlSurfaceView); |
| mUiFrameListener = new FrameListener(mUiTextureHandle, mGlSurfaceView); |
| - mContentFrameListener.mSurfaceTexture.setDefaultBufferSize(width, height); |
| - mUiFrameListener.mSurfaceTexture.setDefaultBufferSize(width, height); |
| + if (mContentSurfaceWidth != -1) { |
| + mContentFrameListener.mSurfaceTexture.setDefaultBufferSize( |
| + mContentSurfaceWidth, mContentSurfaceHeight); |
| + } |
| + if (mUiSurfaceWidth != -1) { |
| + mUiFrameListener.mSurfaceTexture.setDefaultBufferSize( |
| + mUiSurfaceWidth, mUiSurfaceHeight); |
| + } |
| + mSurfacesInitialized = true; |
| ThreadUtils.postOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| - nativeContentSurfaceChanged(mNativeVrShell, width, height, |
| - new Surface(mContentFrameListener.mSurfaceTexture)); |
| - mContentCVC.onPhysicalBackingSizeChanged(width, height); |
| - nativeUiSurfaceChanged(mNativeVrShell, width, height, |
| + nativeSurfacesChanged(mNativeVrShell, |
| + new Surface(mContentFrameListener.mSurfaceTexture), |
| new Surface(mUiFrameListener.mSurfaceTexture)); |
| - mUiCVC.onPhysicalBackingSizeChanged(width, height); |
| } |
| }); |
| @@ -312,6 +425,8 @@ public class VrShellImpl extends GvrLayout implements GLSurfaceView.Renderer, Vr |
| } |
| restoreContentWindow(); |
| mUiContents.destroy(); |
| + mContentVirtualDisplay.destroy(); |
| + mUiVirtualDisplay.destroy(); |
| } |
| @Override |
| @@ -372,10 +487,11 @@ public class VrShellImpl extends GvrLayout implements GLSurfaceView.Renderer, Vr |
| private native void nativeOnTriggerEvent(long nativeVrShell); |
| private native void nativeOnPause(long nativeVrShell); |
| private native void nativeOnResume(long nativeVrShell); |
| - private native void nativeContentSurfaceChanged( |
| - long nativeVrShell, int width, int height, Surface surface); |
| - private native void nativeUiSurfaceChanged( |
| - long nativeVrShell, int width, int height, Surface surface); |
| + private native void nativeSurfacesChanged( |
| + long nativeVrShell, Surface contentSurface, Surface uiSurface); |
| + private native void nativeContentBoundsChanged(long nativeVrShell, int width, int height, |
| + float dpr); |
| + private native void nativeUIBoundsChanged(long nativeVrShell, int width, int height, float dpr); |
| private native void nativeUpdateCompositorLayers(long nativeVrShell); |
| private native void nativeSetWebVrMode(long nativeVrShell, boolean enabled); |
| } |