Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement TimeWarp Layers #778

Merged
merged 2 commits into from Nov 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions app/CMakeLists.txt
Expand Up @@ -24,18 +24,20 @@ add_library( # Sets the name of the library.
src/main/cpp/ControllerContainer.cpp
src/main/cpp/DeviceUtils.cpp
src/main/cpp/ElbowModel.cpp
src/main/cpp/FadeBlitter.cpp
src/main/cpp/GestureDelegate.cpp
src/main/cpp/FadeAnimation.cpp
src/main/cpp/Quad.cpp
src/main/cpp/ExternalBlitter.cpp
src/main/cpp/ExternalVR.cpp
src/main/cpp/GeckoSurfaceTexture.cpp
src/main/cpp/GestureDelegate.cpp
src/main/cpp/LoadingAnimation.cpp
src/main/cpp/JNIUtil.cpp
src/main/cpp/Skybox.cpp
src/main/cpp/SplashAnimation.cpp
src/main/cpp/VRBrowser.cpp
src/main/cpp/VRVideo.cpp
src/main/cpp/VRLayer.cpp
src/main/cpp/VRLayerNode.cpp
src/main/cpp/Widget.cpp
src/main/cpp/WidgetPlacement.cpp
src/main/cpp/WidgetResizer.cpp
Expand Down
47 changes: 44 additions & 3 deletions app/src/common/shared/org/mozilla/vrbrowser/VRBrowserActivity.java
Expand Up @@ -21,6 +21,7 @@
import android.util.Log;
import android.util.Pair;
import android.view.KeyEvent;
import android.view.Surface;
import android.view.View;
import android.widget.FrameLayout;

Expand Down Expand Up @@ -48,6 +49,7 @@
import org.mozilla.vrbrowser.ui.widgets.RootWidget;
import org.mozilla.vrbrowser.ui.widgets.TopBarWidget;
import org.mozilla.vrbrowser.ui.widgets.TrayWidget;
import org.mozilla.vrbrowser.ui.widgets.UIWidget;
import org.mozilla.vrbrowser.ui.widgets.VideoProjectionMenuWidget;
import org.mozilla.vrbrowser.ui.widgets.Widget;
import org.mozilla.vrbrowser.ui.widgets.WidgetManagerDelegate;
Expand Down Expand Up @@ -421,14 +423,47 @@ public void onFrameAvailable(SurfaceTexture surfaceTexture) {
});
}

@Keep
@SuppressWarnings("unused")
void dispatchCreateWidgetLayer(final int aHandle, final Surface aSurface, final int aWidth, final int aHeight) {
runOnUiThread(() -> {
final Widget widget = mWidgets.get(aHandle);
if (widget == null) {
Log.e(LOGTAG, "Widget " + aHandle + " not found");
return;
}

Runnable aFirstDrawCallback = null;
if (aSurface != null && !widget.getFirstDraw()) {
aFirstDrawCallback = () -> {
widget.setFirstDraw(true);
updateWidget(widget);
};
}

widget.setSurface(aSurface, aWidth, aHeight, aFirstDrawCallback);

View view = (View) widget;
// Add widget to a virtual display for invalidation
if (aSurface != null && view.getParent() == null) {
mWidgetContainer.addView(view, new FrameLayout.LayoutParams(aWidth, aHeight));
} else if (aSurface == null && view.getParent() != null) {
mWidgetContainer.removeView(view);
}
view.postInvalidate();
});
}

@Keep
@SuppressWarnings("unused")
void handleMotionEvent(final int aHandle, final int aDevice, final boolean aPressed, final float aX, final float aY) {
runOnUiThread(() -> {
Widget widget = mWidgets.get(aHandle);
if (widget == null) {
MotionEventGenerator.dispatch(mRootWidget, aDevice, aPressed, aX, aY);

} else if (widget == mBrowserWidget && mBrowserWidget.getBorderWidth() > 0) {
final int border = mBrowserWidget.getBorderWidth();
MotionEventGenerator.dispatch(widget, aDevice, aPressed, aX - border, aY - border);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what happened your comment. Negative number should be okay, but It's probably better to filter out any negative numbers since that would be outside the content anyway. But this is probably fine. If we find any issues I think we should address in followup.

} else {
MotionEventGenerator.dispatch(widget, aDevice, aPressed, aX, aY);
}
Expand Down Expand Up @@ -582,6 +617,12 @@ public boolean isOverrideEnvPathEnabled() {
return SettingsStore.getInstance(this).isEnvironmentOverrideEnabled();
}

@Keep
@SuppressWarnings("unused")
public boolean areLayersEnabled() {
return SettingsStore.getInstance(this).getLayersEnabled();
}

@Keep
@SuppressWarnings("unused")
public String getActiveEnvironment() {
Expand Down Expand Up @@ -657,7 +698,7 @@ public void updateWidget(final Widget aWidget) {
params.width = textureWidth;
params.height = textureHeight;
((View)aWidget).setLayoutParams(params);
aWidget.resizeSurfaceTexture(textureWidth, textureHeight);
aWidget.resizeSurface(textureWidth, textureHeight);
}

boolean visible = aWidget.getPlacement().visible;
Expand Down Expand Up @@ -803,7 +844,7 @@ public void setTrayVisible(boolean visible) {
mTray.show();

} else {
mTray.hide();
mTray.hide(UIWidget.KEEP_WIDGET);
}
}

Expand Down
Expand Up @@ -164,6 +164,9 @@ public void setContext(Context aContext, Bundle aExtras) {
runtimeSettingsBuilder.displayDpiOverride(SettingsStore.getInstance(aContext).getDisplayDpi());
runtimeSettingsBuilder.screenSizeOverride(SettingsStore.getInstance(aContext).getMaxWindowWidth(),
SettingsStore.getInstance(aContext).getMaxWindowHeight());
if (SettingsStore.getInstance(aContext).getLayersEnabled()) {
runtimeSettingsBuilder.useMaxScreenDepth(true);
}

if (BuildConfig.DEBUG) {
runtimeSettingsBuilder.arguments(new String[] { "-purgecaches" });
Expand Down Expand Up @@ -498,23 +501,22 @@ public String getCurrentUri() {
}

public Media getFullScreenVideo() {
Media result = null;
if (mCurrentSession != null) {
State state = mSessions.get(mCurrentSession.hashCode());
if (state == null) {
return result;
}
if (state.mMediaElements.size() > 0) {
return state.mMediaElements.get(state.mMediaElements.size() - 1);
return null;
}
for (Media media: state.mMediaElements) {
if (media.isFullscreen()) {
result = media;
break;
return media;
}
}
if (state.mMediaElements.size() > 0) {
return state.mMediaElements.get(state.mMediaElements.size() - 1);
}
}
return result;

return null;
}

public boolean isInputActive(int aSessionId) {
Expand Down
Expand Up @@ -9,6 +9,7 @@

import org.mozilla.geckoview.GeckoSessionSettings;
import org.mozilla.telemetry.TelemetryHolder;
import org.mozilla.vrbrowser.BuildConfig;
import org.mozilla.vrbrowser.R;
import org.mozilla.vrbrowser.telemetry.TelemetryWrapper;

Expand Down Expand Up @@ -305,4 +306,11 @@ public void setMSAALevel(int level) {
editor.commit();
}

public boolean getLayersEnabled() {
if (BuildConfig.FLAVOR_platform.equalsIgnoreCase("oculusvr")) {
return true;
}
return false;
}

}
Expand Up @@ -172,7 +172,7 @@ public void releaseWidget() {

@Override
protected void onDismiss() {
hide();
hide(REMOVE_WIDGET);

if (mPromptDelegate != null) {
mPromptDelegate.onDismissed(getDefaultChoices(mListItems));
Expand Down
Expand Up @@ -43,11 +43,13 @@ public class BrowserWidget extends View implements Widget, SessionStore.SessionC
private ChoicePromptWidget mChoicePrompt;
private int mWidthBackup;
private int mHeightBackup;
private int mBorderWidth;

public BrowserWidget(Context aContext, int aSessionId) {
super(aContext);
mSessionId = aSessionId;
mWidgetManager = (WidgetManagerDelegate) aContext;
mBorderWidth = SettingsStore.getInstance(aContext).getLayersEnabled() ? 1 : 0;
SessionStore.get().addSessionChangeListener(this);
SessionStore.get().addPromptListener(this);
setFocusable(true);
Expand All @@ -65,14 +67,15 @@ public BrowserWidget(Context aContext, int aSessionId) {

private void initializeWidgetPlacement(WidgetPlacement aPlacement) {
Context context = getContext();
aPlacement.width = SettingsStore.getInstance(getContext()).getWindowWidth();
aPlacement.height = SettingsStore.getInstance(getContext()).getWindowHeight();
aPlacement.width = SettingsStore.getInstance(getContext()).getWindowWidth() + mBorderWidth * 2;
aPlacement.height = SettingsStore.getInstance(getContext()).getWindowHeight() + mBorderWidth * 2;
aPlacement.density = 1.0f;
aPlacement.translationX = 0.0f;
aPlacement.translationY = WidgetPlacement.unitFromMeters(context, R.dimen.browser_world_y);
aPlacement.translationZ = WidgetPlacement.unitFromMeters(context, R.dimen.browser_world_z);
aPlacement.anchorX = 0.5f;
aPlacement.anchorY = 0.0f;
aPlacement.visible = true;
}

public void pauseCompositor() {
Expand All @@ -91,31 +94,37 @@ public void resumeCompositor() {
return;
}

mDisplay.surfaceChanged(mSurface, mWidth, mHeight);
callSurfaceChanged();
}

public void enableVRVideoMode(int aVideoWidth, int aVideoHeight) {
public void enableVRVideoMode(int aVideoWidth, int aVideoHeight, boolean aResetBorder) {
mWidthBackup = mWidth;
mHeightBackup = mHeight;
if (aVideoWidth == mWidth && aVideoHeight == mHeight) {
boolean borderChanged = aResetBorder && mBorderWidth > 0;
if (aVideoWidth == mWidth && aVideoHeight == mHeight && !borderChanged) {
return;
}
mWidgetPlacement.width = aVideoWidth;
mWidgetPlacement.height = aVideoHeight;
resizeSurfaceTexture(aVideoWidth, aVideoHeight);
if (aResetBorder) {
mBorderWidth = 0;
}
mWidgetPlacement.width = aVideoWidth + mBorderWidth * 2;
mWidgetPlacement.height = aVideoHeight + mBorderWidth * 2;
resizeSurface(aVideoWidth, aVideoHeight);
Log.e(LOGTAG, "onMetadataChange resize browser " + aVideoWidth + " " + aVideoHeight);
}

public void disableVRVideoMode() {
if (mWidthBackup == 0 || mHeightBackup == 0) {
return;
}
if (mWidthBackup == mWidth && mHeightBackup == mHeight) {
int border = SettingsStore.getInstance(getContext()).getLayersEnabled() ? 1 : 0;
if (mWidthBackup == mWidth && mHeightBackup == mHeight && border == mBorderWidth) {
return;
}
mBorderWidth = border;
mWidgetPlacement.width = mWidthBackup;
mWidgetPlacement.height = mHeightBackup;
resizeSurfaceTexture(mWidthBackup, mWidthBackup);
resizeSurface(mWidthBackup, mWidthBackup);
}

public void setBrowserSize(float windowWidth, float windowHeight, float multiplier) {
Expand All @@ -130,6 +139,18 @@ public void setBrowserSize(float windowWidth, float windowHeight, float multipli
handleResizeEvent(targetWidth, targetHeight);
}

public int getBorderWidth() {
return mBorderWidth;
}

public int getTextureWidth() {
return mWidth;
}

public int getTextureHeight() {
return mHeight;
}

@Override
public void setSurfaceTexture(SurfaceTexture aTexture, final int aWidth, final int aHeight) {
GeckoSession session = SessionStore.get().getSession(mSessionId);
Expand All @@ -146,15 +167,45 @@ public void setSurfaceTexture(SurfaceTexture aTexture, final int aWidth, final i
} else {
Log.e(LOGTAG, "GeckoDisplay was not null in BrowserWidget.setSurfaceTexture()");
}
mDisplay.surfaceChanged(mSurface, aWidth, aHeight);
callSurfaceChanged();
}

@Override
public void setSurface(Surface aSurface, final int aWidth, final int aHeight, Runnable aFirstDrawCallback) {
GeckoSession session = SessionStore.get().getSession(mSessionId);
if (session == null) {
return;
}
mWidth = aWidth;
mHeight = aHeight;
mSurface = aSurface;
if (mDisplay == null) {
mDisplay = session.acquireDisplay();
} else {
Log.e(LOGTAG, "GeckoDisplay was not null in BrowserWidget.setSurfaceTexture()");
}
if (mSurface != null) {
callSurfaceChanged();
} else {
mDisplay.surfaceDestroyed();
}
if (aFirstDrawCallback != null) {
aFirstDrawCallback.run();
}
}

private void callSurfaceChanged() {
mDisplay.surfaceChanged(mSurface, mBorderWidth, mBorderWidth, mWidth - mBorderWidth * 2, mHeight - mBorderWidth * 2);
bluemarvin marked this conversation as resolved.
Show resolved Hide resolved
}

@Override
public void resizeSurfaceTexture(final int aWidth, final int aHeight) {
public void resizeSurface(final int aWidth, final int aHeight) {
mWidth = aWidth;
mHeight = aHeight;
mSurfaceTexture.setDefaultBufferSize(aWidth, aHeight);
mDisplay.surfaceChanged(mSurface, aWidth, aHeight);
if (mSurfaceTexture != null) {
mSurfaceTexture.setDefaultBufferSize(aWidth, aHeight);
}
callSurfaceChanged();
}

@Override
Expand Down Expand Up @@ -197,8 +248,8 @@ public void handleResizeEvent(float aWorldWidth, float aWorldHeight) {

float aspect = (float)defaultWidth / (float)defaultHeight;
float worldHeight = worldWidth / aspect;
mWidgetPlacement.width = (int)((aWorldWidth * defaultWidth) / worldWidth);
mWidgetPlacement.height = (int)((aWorldHeight * defaultHeight) /worldHeight);
mWidgetPlacement.width = (int)((aWorldWidth * defaultWidth) / worldWidth) + mBorderWidth * 2;
mWidgetPlacement.height = (int)((aWorldHeight * defaultHeight) /worldHeight) + mBorderWidth * 2;
mWidgetPlacement.worldWidth = aWorldWidth;
mWidgetManager.updateWidget(this);

Expand Down Expand Up @@ -281,7 +332,7 @@ public void onCurrentSessionChange(GeckoSession aSession, int aId) {
mSessionId = aId;
mDisplay = aSession.acquireDisplay();
Log.d(LOGTAG, "surfaceChanged: " + aId);
mDisplay.surfaceChanged(mSurface, mWidth, mHeight);
callSurfaceChanged();
aSession.getTextInput().setView(this);

boolean isPrivateMode = aSession.getSettings().getBoolean(GeckoSessionSettings.USE_PRIVATE_MODE);
Expand Down Expand Up @@ -410,7 +461,7 @@ public void onChoicePrompt(GeckoSession session, String title, String msg, int t
@Override
public void onDismissed(String[] ids) {
callback.confirm(ids);
mChoicePrompt.hide();
mChoicePrompt.hide(UIWidget.REMOVE_WIDGET);
}
});

Expand Down
Expand Up @@ -91,7 +91,7 @@ private void initialize(Context aContext) {
mAudio.playSound(AudioEngine.Sound.CLICK);
}

hide();
hide(REMOVE_WIDGET);

if(mCrashDialogDelegate != null) {
mCrashDialogDelegate.onSendData();
Expand Down Expand Up @@ -142,8 +142,8 @@ public void show() {
}

@Override
public void hide() {
super.hide();
public void hide(@HideFlags int aHideFlags) {
super.hide(aHideFlags);

mWidgetManager.popWorldBrightness(this);
}
Expand Down
Expand Up @@ -184,7 +184,7 @@ public void show() {
}

private void showRestartDialog() {
hide();
hide(REMOVE_WIDGET);

UIWidget widget = getChild(mRestartDialogHandle);
if (widget == null) {
Expand Down