Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.

Enable Oculus Fixed Foveated Rendering #654

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions app/src/common/shared/org/mozilla/vrbrowser/VRBrowserActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,12 @@ public int getPointerColor() {
return SettingsStore.getInstance(this).getPointerColor();
}

@Keep
@SuppressWarnings("unused")
public int getFoveatedLevel() {
return SettingsStore.getInstance(this).getFoveatedLevel();
}

void createOffscreenDisplay() {
int[] ids = new int[1];
GLES20.glGenTextures(1, ids, 0);
Expand Down Expand Up @@ -815,6 +821,11 @@ public void updateEnvironment() {
queueRunnable(() -> updateEnvironmentNative());
}

@Override
public void updateFoveatedLevel() {
queueRunnable(() -> updateFoveatedLevelNative());
}

@Override
public void updatePointerColor() {
queueRunnable(() -> updatePointerColorNative());
Expand Down Expand Up @@ -854,4 +865,5 @@ public void onRequestPermissionsResult(int requestCode, String[] permissions, in
private native void workaroundGeckoSigAction();
private native void updateEnvironmentNative();
private native void updatePointerColorNative();
private native void updateFoveatedLevelNative();
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ SettingsStore getInstance(final @NonNull Context aContext) {
public final static float BROWSER_WORLD_WIDTH_DEFAULT = 4.0f;
public final static float BROWSER_WORLD_HEIGHT_DEFAULT = 2.25f;
public final static int MSAA_DEFAULT_LEVEL = 1;
public final static int FOVEATED_DEFAULT_LEVEL = 2;

// Enable telemetry by default (opt-out).
private final static boolean enableCrashReportingByDefault = false;
Expand Down Expand Up @@ -304,4 +305,14 @@ public void setMSAALevel(int level) {
editor.commit();
}

public int getFoveatedLevel() {
return mPrefs.getInt(
mContext.getString(R.string.settings_key_foveated), FOVEATED_DEFAULT_LEVEL);
}

public void setFoveatedLevel(int level) {
SharedPreferences.Editor editor = mPrefs.edit();
editor.putInt(mContext.getString(R.string.settings_key_foveated), level);
editor.commit();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.mozilla.vrbrowser.R;
import org.mozilla.vrbrowser.browser.SessionStore;
import org.mozilla.vrbrowser.browser.SettingsStore;
import org.mozilla.vrbrowser.BuildConfig;
import org.mozilla.vrbrowser.audio.AudioEngine;
import org.mozilla.vrbrowser.ui.views.UIButton;
import org.mozilla.vrbrowser.ui.settings.ButtonSetting;
Expand Down Expand Up @@ -41,6 +42,7 @@ public class DeveloperOptionsWidget extends UIWidget {
private RadioGroupSetting mPointerColorRadio;
private RadioGroupSetting mUaModeRadio;
private RadioGroupSetting mMSAARadio;
private RadioGroupSetting mFoveatedRadio;

private SingleEditSetting mDensityEdit;
private SingleEditSetting mDpiEdit;
Expand Down Expand Up @@ -127,6 +129,15 @@ public void onClick(View view) {
mMSAARadio.setOnCheckedChangeListener(mMSSAChangeListener);
setMSAAMode(mMSAARadio.getIdForValue(msaaLevel), false);

mFoveatedRadio = findViewById(R.id.foveated_radio);
if (BuildConfig.FLAVOR_platform == "oculusvr") {
int foveatedLevel = SettingsStore.getInstance(getContext()).getFoveatedLevel();
mFoveatedRadio.setOnCheckedChangeListener(mFoveatedChangeListener);
setFoveatedLevel(mFoveatedRadio.getIdForValue(foveatedLevel), false);
} else {
mFoveatedRadio.setVisibility(View.GONE);
}

mDensityEdit = findViewById(R.id.density_edit);
mDensityEdit.setFirstText(Float.toString(SettingsStore.getInstance(getContext()).getDisplayDensity()));
mDensityEdit.setOnClickListener(mDensityListener);
Expand Down Expand Up @@ -245,6 +256,13 @@ public void onCheckedChanged(RadioGroup radioGroup, int checkedId, boolean doApp
}
};

private RadioGroupSetting.OnCheckedChangeListener mFoveatedChangeListener = new RadioGroupSetting.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int checkedId, boolean doApply) {
setFoveatedLevel(checkedId, true);
}
};

private RadioGroupSetting.OnCheckedChangeListener mEnvsListener = new RadioGroupSetting.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int checkedId, boolean doApply) {
Expand Down Expand Up @@ -414,6 +432,18 @@ private void setMSAAMode(int checkedId, boolean doApply) {
}
}

private void setFoveatedLevel(int checkedId, boolean doApply) {
mFoveatedRadio.setOnCheckedChangeListener(null);
mFoveatedRadio.setChecked(checkedId, doApply);
mFoveatedRadio.setOnCheckedChangeListener(mFoveatedChangeListener);

SettingsStore.getInstance(getContext()).setFoveatedLevel((Integer)mFoveatedRadio.getValueForId(checkedId));

if (doApply) {
mWidgetManager.updateFoveatedLevel();
}
}

private void setEnv(int checkedId, boolean doApply) {
mEnvironmentsRadio.setOnCheckedChangeListener(null);
mEnvironmentsRadio.setChecked(checkedId, doApply);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ interface WorldClickListener {
void setBrowserSize(float targetWidth, float targetHeight);
void keyboardDismissed();
void updateEnvironment();
void updateFoveatedLevel();
void updatePointerColor();
void addFocusChangeListener(@NonNull FocusChangeListener aListener);
void removeFocusChangeListener(@NonNull FocusChangeListener aListener);
Expand Down
5 changes: 5 additions & 0 deletions app/src/googlevr/cpp/DeviceDelegateGoogleVR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,11 @@ DeviceDelegateGoogleVR::SetControllerDelegate(ControllerDelegatePtr& aController
}
}

void
DeviceDelegateGoogleVR::SetFoveatedLevel(const uint32_t aLevel) {
// Not Supported
}

void
DeviceDelegateGoogleVR::ReleaseControllerDelegate() {
m.controllerDelegate = nullptr;
Expand Down
1 change: 1 addition & 0 deletions app/src/googlevr/cpp/DeviceDelegateGoogleVR.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class DeviceDelegateGoogleVR : public DeviceDelegate {
void SetClipPlanes(const float aNear, const float aFar) override;
void SetControllerDelegate(ControllerDelegatePtr& aController) override;
void ReleaseControllerDelegate() override;
void SetFoveatedLevel(const uint32_t aLevel) override;
int32_t GetControllerModelCount() const override;
const std::string GetControllerModelName(const int32_t aModelIndex) const override;
void ProcessEvents() override;
Expand Down
30 changes: 21 additions & 9 deletions app/src/main/cpp/BrowserWorld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ BrowserWorld::InitializeJava(JNIEnv* aEnv, jobject& aActivity, jobject& aAssetMa
m.loadingAnimation->LoadModels(m.loader);
m.rootController->AddNode(m.controllers->GetRoot());
std::string skyboxPath = VRBrowser::GetActiveEnvironment();
m.device->SetFoveatedLevel(VRBrowser::GetFoveatedLevel());
if (VRBrowser::isOverrideEnvPathEnabled()) {
std::string storagePath = VRBrowser::GetStorageAbsolutePath(INJECT_SKYBOX_PATH);
if (std::ifstream(storagePath)) {
Expand Down Expand Up @@ -646,6 +647,12 @@ BrowserWorld::UpdateEnvironment() {
m.rootOpaqueParent->AddNode(m.skybox);
}

void
BrowserWorld::UpdateFoveatedLevel() {
ASSERT_ON_RENDER_THREAD();
m.device->SetFoveatedLevel(VRBrowser::GetFoveatedLevel());
}

void
BrowserWorld::UpdatePointerColor() {
ASSERT_ON_RENDER_THREAD();
Expand Down Expand Up @@ -1147,33 +1154,33 @@ BrowserWorld::DistanceToPlane(const WidgetPtr& aWidget, const vrb::Vector& aPosi
extern "C" {

JNI_METHOD(void, addWidgetNative)
(JNIEnv* aEnv, jobject, jint aHandle, jobject aPlacement) {
(JNIEnv *aEnv, jobject, jint aHandle, jobject aPlacement) {
crow::WidgetPlacementPtr placement = crow::WidgetPlacement::FromJava(aEnv, aPlacement);
if (placement) {
crow::BrowserWorld::Instance().AddWidget(aHandle, placement);
}
}

JNI_METHOD(void, updateWidgetNative)
(JNIEnv* aEnv, jobject, jint aHandle, jobject aPlacement) {
(JNIEnv *aEnv, jobject, jint aHandle, jobject aPlacement) {
crow::WidgetPlacementPtr placement = crow::WidgetPlacement::FromJava(aEnv, aPlacement);
if (placement) {
crow::BrowserWorld::Instance().UpdateWidget(aHandle, placement);
}
}

JNI_METHOD(void, removeWidgetNative)
(JNIEnv*, jobject, jint aHandle) {
(JNIEnv *, jobject, jint aHandle) {
crow::BrowserWorld::Instance().RemoveWidget(aHandle);
}

JNI_METHOD(void, startWidgetResizeNative)
(JNIEnv*, jobject, jint aHandle) {
(JNIEnv *, jobject, jint aHandle) {
crow::BrowserWorld::Instance().StartWidgetResize(aHandle);
}

JNI_METHOD(void, finishWidgetResizeNative)
(JNIEnv*, jobject, jint aHandle) {
(JNIEnv *, jobject, jint aHandle) {
crow::BrowserWorld::Instance().FinishWidgetResize(aHandle);
}

Expand All @@ -1183,20 +1190,20 @@ JNI_METHOD(void, setWorldBrightnessNative)
}

JNI_METHOD(void, setTemporaryFilePath)
(JNIEnv* aEnv, jobject, jstring aPath) {
(JNIEnv *aEnv, jobject, jstring aPath) {
const char *nativeString = aEnv->GetStringUTFChars(aPath, 0);
std::string path = nativeString;
aEnv->ReleaseStringUTFChars(aPath, nativeString);
crow::BrowserWorld::Instance().SetTemporaryFilePath(path);
}

JNI_METHOD(void, exitImmersiveNative)
(JNIEnv* aEnv, jobject) {
(JNIEnv *aEnv, jobject) {
crow::BrowserWorld::Instance().ExitImmersive();
}

JNI_METHOD(void, workaroundGeckoSigAction)
(JNIEnv*, jobject) {
(JNIEnv *, jobject) {
if (putenv(strdup("MOZ_DISABLE_SIG_HANDLER=1")) == 0) {
VRB_DEBUG("Successfully set MOZ_DISABLE_SIG_HANDLER");
} else {
Expand All @@ -1210,10 +1217,15 @@ JNI_METHOD(void, workaroundGeckoSigAction)
}

JNI_METHOD(void, updateEnvironmentNative)
(JNIEnv* aEnv, jobject) {
(JNIEnv *aEnv, jobject) {
crow::BrowserWorld::Instance().UpdateEnvironment();
}

JNI_METHOD(void, updateFoveatedLevelNative)
(JNIEnv *aEnv, jobject) {
crow::BrowserWorld::Instance().UpdateFoveatedLevel();
}

JNI_METHOD(void, updatePointerColorNative)
(JNIEnv* aEnv, jobject) {
crow::BrowserWorld::Instance().UpdatePointerColor();
Expand Down
1 change: 1 addition & 0 deletions app/src/main/cpp/BrowserWorld.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class BrowserWorld {
void Draw();
void SetTemporaryFilePath(const std::string& aPath);
void UpdateEnvironment();
void UpdateFoveatedLevel();
void UpdatePointerColor();
void SetSurfaceTexture(const std::string& aName, jobject& aSurface);
void AddWidget(int32_t aHandle, const WidgetPlacementPtr& placement);
Expand Down
1 change: 1 addition & 0 deletions app/src/main/cpp/DeviceDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class DeviceDelegate {
virtual void SetClearColor(const vrb::Color& aColor) = 0;
virtual void SetClipPlanes(const float aNear, const float aFar) = 0;
virtual void SetControllerDelegate(ControllerDelegatePtr& aController) = 0;
virtual void SetFoveatedLevel(const uint32_t aLevel) = 0;
virtual void ReleaseControllerDelegate() = 0;
virtual int32_t GetControllerModelCount() const = 0;
virtual const std::string GetControllerModelName(const int32_t aModelIndex) const = 0;
Expand Down
14 changes: 13 additions & 1 deletion app/src/main/cpp/VRBrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ static const char* kGetActiveEnvironment = "getActiveEnvironment";
static const char* kGetActiveEnvironmentSignature = "()Ljava/lang/String;";
static const char* kGetPointerColor = "getPointerColor";
static const char* kGetPointerColorSignature = "()I";

static const char* kGetFoveatedLevel = "getFoveatedLevel";
static const char* kGetFoveatedLevelSignature = "()I";
static JNIEnv* sEnv;
static jobject sActivity;
static jmethodID sDispatchCreateWidget;
Expand All @@ -55,6 +56,7 @@ static jmethodID sGetStorageAbsolutePath;
static jmethodID sIsOverrideEnvPathEnabled;
static jmethodID sGetActiveEnvironment;
static jmethodID sGetPointerColor;
static jmethodID sGetFoveatedLevel;
}

namespace crow {
Expand Down Expand Up @@ -88,6 +90,7 @@ VRBrowser::InitializeJava(JNIEnv* aEnv, jobject aActivity) {
sIsOverrideEnvPathEnabled = FindJNIMethodID(sEnv, browserClass, kIsOverrideEnvPathEnabledName, kIsOverrideEnvPathEnabledSignature);
sGetActiveEnvironment = FindJNIMethodID(sEnv, browserClass, kGetActiveEnvironment, kGetActiveEnvironmentSignature);
sGetPointerColor = FindJNIMethodID(sEnv, browserClass, kGetPointerColor, kGetPointerColorSignature);
sGetFoveatedLevel = FindJNIMethodID(sEnv, browserClass, kGetFoveatedLevel, kGetFoveatedLevelSignature);
}

void
Expand Down Expand Up @@ -237,4 +240,13 @@ VRBrowser::GetPointerColor() {
return (int32_t )jHexColor;
}

int32_t
VRBrowser::GetFoveatedLevel() {
if (!ValidateMethodID(sEnv, sActivity, sGetFoveatedLevel, __FUNCTION__)) { return 16777215; }
jint jFoveatedLevel = (jint) sEnv->CallIntMethod(sActivity, sGetFoveatedLevel);
CheckJNIException(sEnv, __FUNCTION__);

return (int32_t )jFoveatedLevel;
}

} // namespace crow
1 change: 1 addition & 0 deletions app/src/main/cpp/VRBrowser.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ std::string GetStorageAbsolutePath(const std::string& aRelativePath);
bool isOverrideEnvPathEnabled();
std::string GetActiveEnvironment();
int32_t GetPointerColor();
int32_t GetFoveatedLevel();
} // namespace VRBrowser;

} // namespace crow
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/res/layout/developer_options.xml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@
app:options="@array/developer_options_msaa_options"
app:values="@array/developer_options_ua_mode_values"/>

<org.mozilla.vrbrowser.ui.settings.RadioGroupSetting
android:id="@+id/foveated_radio"
android:layout_width="match_parent"
android:layout_height="60dp"
app:description="@string/developer_options_foveated"
app:options="@array/developer_options_foveated_options"
app:values="@array/developer_options_ua_mode_values"/>

<org.mozilla.vrbrowser.ui.settings.SingleEditSetting
android:id="@+id/density_edit"
android:layout_width="match_parent"
Expand Down
7 changes: 7 additions & 0 deletions app/src/main/res/values/non_L10n.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<string name="settings_key_env" translatable="false">settings_env</string>
<string name="settings_key_pointer_color" translatable="false">settings_pointer_color</string>
<string name="settings_key_msaa" translatable="false">settings_msaa</string>
<string name="settings_key_foveated" translatable="false">settings_foveated</string>
<string name="private_browsing_support_url" translatable="false">https://support.mozilla.org/kb/private-mode-firefox-reality</string>
<string name="settings_key_browser_world_width" translatable="false">settings_browser_world_width</string>
<string name="settings_key_browser_world_height" translatable="false">settings_browser_world_height</string>
Expand Down Expand Up @@ -72,4 +73,10 @@
<item>@string/developer_options_msaa_2</item>
<item>@string/developer_options_msaa_4</item>
</string-array>
<string-array name="developer_options_foveated_options" translatable="false">
<item>@string/developer_options_foveated_disabled</item>
<item>@string/developer_options_foveated_1</item>
<item>@string/developer_options_foveated_2</item>
<item>@string/developer_options_foveated_3</item>
</string-array>
</resources>
1 change: 1 addition & 0 deletions app/src/main/res/values/settings_values.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
</integer-array>
</resources>
15 changes: 15 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,21 @@
<string name="developer_options_msaa_2">2x</string>
<!-- This string is used to label the MSAA radio button that enables four times MSAA in immersive mode. -->
<string name="developer_options_msaa_4">4x</string>
<!-- This string is used to label radio buttons for setting fixed-foveated-rendering (FFR) level.
Higher values of this option result in larger parts of the peripheral vision being rendered
at lower resolutions than the content in the center of the view. These higher values reduce
quality to increase performance. The Oculus implementation of fixed-foveated-rendering is
described in more detail here:
https://developer.oculus.com/blog/optimizing-oculus-go-for-performance/-->
<string name="developer_options_foveated">Foveation Level</string>
<!-- This string is used to label the Foveated radio button that disables fixed-foveated-rendering in immersive mode. -->
<string name="developer_options_foveated_disabled">Disabled</string>
<!-- This string is used to label the Foveated radio button that enables low-level fixed-foveated-rendering. -->
<string name="developer_options_foveated_1">1</string>
Copy link
Contributor

Choose a reason for hiding this comment

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

could we call these Low, Medium, and High?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can only really notice the difference between #2 and #3. With #3, you can see the edges having a slightly lower resolution when you move the headset so something with contrast is near the top or sides.

I originally wanted to use "low", "medium", and "high" but the longer strings broke the UI causing overlaps. Perhaps we could improve this later with some changes to the developer options panel layout?

<!-- This string is used to label the Foveated radio button that enables medium-level fixed-foveated-rendering. -->
<string name="developer_options_foveated_2">2</string>
<!-- This string is used to label the Foveated radio button that enables high-level fixed-foveated-rendering. -->
<string name="developer_options_foveated_3">3</string>
<!-- This string is used to label a set of radio buttons that allow the user to
change the user-agent (UA) string of the browser. -->
<string name="developer_options_ua_mode">User-Agent Mode</string>
Expand Down
5 changes: 5 additions & 0 deletions app/src/noapi/cpp/DeviceDelegateNoAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ DeviceDelegateNoAPI::ReleaseControllerDelegate() {
m.controller = nullptr;
}

void
DeviceDelegateNoAPI::SetFoveatedLevel(const uint32_t aLevel) {
// Not Supported
}

int32_t
DeviceDelegateNoAPI::GetControllerModelCount() const {
return 0;
Expand Down
1 change: 1 addition & 0 deletions app/src/noapi/cpp/DeviceDelegateNoAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class DeviceDelegateNoAPI : public DeviceDelegate {
void SetClipPlanes(const float aNear, const float aFar) override;
void SetControllerDelegate(ControllerDelegatePtr& aController) override;
void ReleaseControllerDelegate() override;
void SetFoveatedLevel(const uint32_t aLevel) override;
int32_t GetControllerModelCount() const override;
const std::string GetControllerModelName(const int32_t aModelIndex) const override;
void ProcessEvents() override;
Expand Down
Loading