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

Commit

Permalink
Using Surface from swap chains to render immersive frames instead of …
Browse files Browse the repository at this point in the history
…framebuffer textures.
  • Loading branch information
daoshengmu committed Sep 5, 2019
1 parent 845e99b commit 94fe049
Show file tree
Hide file tree
Showing 11 changed files with 160 additions and 21 deletions.
19 changes: 19 additions & 0 deletions app/src/common/shared/org/mozilla/vrbrowser/VRBrowserActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,25 @@ public void dismiss() {
});
}

public void setExternalVRSurfaceLength(int aLen) {
GeckoVRManager.setExternalSurfaceLength(aLen);
}

public void setExternalVRSurfaceIndex(int aIndex) {
GeckoVRManager.setExternalSurfaceIndex(aIndex);
}

public void setExternalVRSurface(int aIndex, Surface aSurface) {
if (aSurface == null) {
Log.e(LOGTAG, "aSurface is null in setExternalVRSurface...");
}
GeckoVRManager.insertExternalSurface(aIndex, aSurface);
}

public void releaseExternalVRSurfaces() {
GeckoVRManager.releaseExternalSurfaces();
}

void createOffscreenDisplay() {
int[] ids = new int[1];
GLES20.glGenTextures(1, ids, 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.mozilla.gecko.GeckoProfile;
import org.mozilla.vrbrowser.BuildConfig;
import org.mozilla.vrbrowser.browser.SettingsStore;
import org.mozilla.vrbrowser.utils.DeviceType;

import java.io.File;
import java.io.FileNotFoundException;
Expand Down Expand Up @@ -55,6 +56,12 @@ public static void vrPrefsWorkAround(Context aContext, Bundle aExtras) {
out.write("pref(\"media.autoplay.enabled.ask-permission\", false);\n".getBytes());
out.write("pref(\"media.autoplay.default\", 0);\n".getBytes());
}
// In Oculus platform, we can render WebGL immersive frames info AndroidSurface.
if (DeviceType.isOculusBuild()) {
out.write("pref(\"webgl.enable-externalvr-surface\", true);\n".getBytes());
} else {
out.write("pref(\"webgl.enable-externalvr-surface\", false);\n".getBytes());
}
} catch (FileNotFoundException e) {
Log.e(LOGTAG, "Unable to create file: '" + prefFileName + "' got exception: " + e.toString());
} catch (IOException e) {
Expand Down
19 changes: 13 additions & 6 deletions app/src/main/cpp/BrowserWorld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1190,6 +1190,7 @@ void
BrowserWorld::DrawWorld() {
m.externalVR->SetCompositorEnabled(true);
m.device->SetRenderMode(device::RenderMode::StandAlone);
m.device->EnableExternalSurfaceRender(false);
if (m.fadeAnimation) {
m.fadeAnimation->UpdateAnimation();
}
Expand Down Expand Up @@ -1257,23 +1258,29 @@ BrowserWorld::DrawImmersive() {
m.device->StartFrame();
VRB_GL_CHECK(glDepthMask(GL_FALSE));
m.externalVR->PushFramePoses(m.device->GetHeadTransform(), m.controllers->GetControllers(), m.context->GetTimestamp());
mozilla::gfx::VRLayerTextureType surfaceType;
int32_t surfaceHandle, textureWidth, textureHeight = 0;
device::EyeRect leftEye, rightEye;
bool aDiscardFrame = !m.externalVR->WaitFrameResult();
m.externalVR->GetFrameResult(surfaceHandle, textureWidth, textureHeight, leftEye, rightEye);
m.externalVR->GetFrameResult(surfaceType, surfaceHandle, textureWidth, textureHeight, leftEye, rightEye);
ExternalVR::VRState state = m.externalVR->GetVRState();
if (state == ExternalVR::VRState::Rendering) {
if (!aDiscardFrame) {
if (textureWidth > 0 && textureHeight > 0) {
m.device->SetImmersiveSize((uint32_t) textureWidth/2, (uint32_t) textureHeight);
}
m.blitter->StartFrame(surfaceHandle, leftEye, rightEye);
m.device->BindEye(device::Eye::Left);
m.blitter->Draw(device::Eye::Left);
m.device->EnableExternalSurfaceRender(surfaceType ==
mozilla::gfx::VRLayerTextureType::LayerTextureType_ExternalVRSurface);
// In Oculus platform, we can render WebGL immersive frames info AndroidSurface.
if (surfaceType != mozilla::gfx::VRLayerTextureType::LayerTextureType_ExternalVRSurface) {
m.blitter->StartFrame(surfaceHandle, leftEye, rightEye);
m.device->BindEye(device::Eye::Left);
m.blitter->Draw(device::Eye::Left);
#if !defined(VRBROWSER_NO_VR_API)
m.device->BindEye(device::Eye::Right);
m.blitter->Draw(device::Eye::Right);
m.device->BindEye(device::Eye::Right);
m.blitter->Draw(device::Eye::Right);
#endif // !defined(VRBROWSER_NO_VR_API)
}
}
m.device->EndFrame(aDiscardFrame);
m.blitter->EndFrame();
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 @@ -67,6 +67,7 @@ class DeviceDelegate {
virtual void StartFrame() = 0;
virtual void BindEye(const device::Eye aWhich) = 0;
virtual void EndFrame(bool aDiscard = false) = 0;
virtual void EnableExternalSurfaceRender(bool aEnable) {}
virtual VRLayerQuadPtr CreateLayerQuad(int32_t aWidth, int32_t aHeight,
VRLayerSurface::SurfaceType aSurfaceType) { return nullptr; }
virtual VRLayerQuadPtr CreateLayerQuad(const VRLayerSurfacePtr& aMoveLayer) { return nullptr; }
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/cpp/ExternalVR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,10 +476,10 @@ ExternalVR::CompleteEnumeration()
m.system.enumerationCompleted = true;
}


void
ExternalVR::GetFrameResult(int32_t& aSurfaceHandle, int32_t& aTextureWidth, int32_t& aTextureHeight,
ExternalVR::GetFrameResult(mozilla::gfx::VRLayerTextureType& aSurfaceType, int32_t& aSurfaceHandle, int32_t& aTextureWidth, int32_t& aTextureHeight,
device::EyeRect& aLeftEye, device::EyeRect& aRightEye) const {
aSurfaceType = m.browser.layerState[0].layer_stereo_immersive.textureType;
aSurfaceHandle = (int32_t)m.browser.layerState[0].layer_stereo_immersive.textureHandle;
mozilla::gfx::VRLayerEyeRect& left = m.browser.layerState[0].layer_stereo_immersive.leftEyeRect;
mozilla::gfx::VRLayerEyeRect& right = m.browser.layerState[0].layer_stereo_immersive.rightEyeRect;
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/cpp/ExternalVR.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "Controller.h"
#include "DeviceDelegate.h"
#include "Device.h"
#include "moz_external_vr.h"
#include <memory>
#include <string>
#include <vector>
Expand Down Expand Up @@ -54,7 +55,8 @@ class ExternalVR : public ImmersiveDisplay {
VRState GetVRState() const;
void PushFramePoses(const vrb::Matrix& aHeadTransform, const std::vector<Controller>& aControllers, const double aTimestamp);
bool WaitFrameResult();
void GetFrameResult(int32_t& aSurfaceHandle,
void GetFrameResult(mozilla::gfx::VRLayerTextureType& aSurfaceType,
int32_t& aSurfaceHandle,
int32_t& aTextureWidth,
int32_t& aTextureHeight,
device::EyeRect& aLeftEye,
Expand Down
44 changes: 44 additions & 0 deletions app/src/main/cpp/VRBrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ const char* kHaltActivity = "haltActivity";
const char* kHaltActivitySignature = "(I)V";
const char* kHandlePoorPerformance = "handlePoorPerformance";
const char* kHandlePoorPerformanceSignature = "()V";
const char* kSetExternalVRSurfaceLength = "setExternalVRSurfaceLength";
const char* kSetExternalVRSurfaceLengthSignature = "(I)V";
const char* kSetExternalVRSurfaceIndex = "setExternalVRSurfaceIndex";
const char* kSetExternalVRSurfaceIndexSignature = "(I)V";
const char* kSetExternalVRSurface = "setExternalVRSurface";
const char* kSetExternalVRSurfaceSignature = "(ILandroid/view/Surface;)V";
const char* kReleaseExternalSurfaces = "releaseExternalVRSurfaces";
const char* kReleaseExternalSurfacesSignature = "()V";

JNIEnv* sEnv = nullptr;
jclass sBrowserClass = nullptr;
Expand All @@ -77,6 +85,10 @@ jmethodID sAreLayersEnabled = nullptr;
jmethodID sSetDeviceType = nullptr;
jmethodID sHaltActivity = nullptr;
jmethodID sHandlePoorPerformance = nullptr;
jmethodID sSetExternalVRSurfaceLength = nullptr;
jmethodID sSetExternalVRSurfaceIndex = nullptr;
jmethodID sSetExternalVRSurface = nullptr;
jmethodID sReleaseExternalSurfaces = nullptr;
}

namespace crow {
Expand Down Expand Up @@ -117,6 +129,10 @@ VRBrowser::InitializeJava(JNIEnv* aEnv, jobject aActivity) {
sSetDeviceType = FindJNIMethodID(sEnv, sBrowserClass, kSetDeviceType, kSetDeviceTypeSignature);
sHaltActivity = FindJNIMethodID(sEnv, sBrowserClass, kHaltActivity, kHaltActivitySignature);
sHandlePoorPerformance = FindJNIMethodID(sEnv, sBrowserClass, kHandlePoorPerformance, kHandlePoorPerformanceSignature);
sSetExternalVRSurface = FindJNIMethodID(sEnv, sBrowserClass, kSetExternalVRSurface, kSetExternalVRSurfaceSignature);
sSetExternalVRSurfaceLength = FindJNIMethodID(sEnv, sBrowserClass, kSetExternalVRSurfaceLength, kSetExternalVRSurfaceLengthSignature);
sSetExternalVRSurfaceIndex = FindJNIMethodID(sEnv, sBrowserClass, kSetExternalVRSurfaceIndex, kSetExternalVRSurfaceIndexSignature);
sReleaseExternalSurfaces = FindJNIMethodID(sEnv, sBrowserClass, kReleaseExternalSurfaces, kReleaseExternalSurfacesSignature);
}

void
Expand Down Expand Up @@ -151,6 +167,7 @@ VRBrowser::ShutdownJava() {
sAreLayersEnabled = nullptr;
sSetDeviceType = nullptr;
sHaltActivity = nullptr;
sSetExternalVRSurface = nullptr;
sEnv = nullptr;
}

Expand Down Expand Up @@ -339,4 +356,31 @@ VRBrowser::HandlePoorPerformance() {
CheckJNIException(sEnv, __FUNCTION__);
}

void
VRBrowser::SetExternalVRSurfaceLength(jint aLen) {
if (!ValidateMethodID(sEnv, sActivity, sSetExternalVRSurfaceLength, __FUNCTION__)) { return; }
sEnv->CallVoidMethod(sActivity, sSetExternalVRSurfaceLength, aLen);
CheckJNIException(sEnv, __FUNCTION__);
}

void
VRBrowser::SetExternalVRSurfaceId(jint aId) {
if (!ValidateMethodID(sEnv, sActivity, sSetExternalVRSurfaceIndex, __FUNCTION__)) { return; }
sEnv->CallVoidMethod(sActivity, sSetExternalVRSurfaceIndex, aId);
CheckJNIException(sEnv, __FUNCTION__);
}

void
VRBrowser::SetExternalVRSurface(jint aIndex, jobject aSurface) {
if (!ValidateMethodID(sEnv, sActivity, sSetExternalVRSurface, __FUNCTION__)) { return; }
sEnv->CallVoidMethod(sActivity, sSetExternalVRSurface, aIndex, aSurface);
CheckJNIException(sEnv, __FUNCTION__);
}

void
VRBrowser::ReleaseExternalVRSurfaces() {
if (!ValidateMethodID(sEnv, sActivity, sReleaseExternalSurfaces, __FUNCTION__)) { return; }
sEnv->CallVoidMethod(sActivity, sReleaseExternalSurfaces);
CheckJNIException(sEnv, __FUNCTION__);
}
} // namespace crow
4 changes: 4 additions & 0 deletions app/src/main/cpp/VRBrowser.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ bool AreLayersEnabled();
void SetDeviceType(const jint aType);
void HaltActivity(const jint aReason);
void HandlePoorPerformance();
void SetExternalVRSurfaceLength(jint aLen);
void SetExternalVRSurfaceId(jint aId);
void SetExternalVRSurface(jint aIndex, jobject aSurface);
void ReleaseExternalVRSurfaces();
} // namespace VRBrowser;

} // namespace crow
Expand Down
5 changes: 3 additions & 2 deletions app/src/main/cpp/moz_external_vr.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ enum class GamepadCapabilityFlags : uint16_t;
#endif // MOZILLA_INTERNAL_API
namespace gfx {

static const int32_t kVRExternalVersion = 9;
static const int32_t kVRExternalVersion = 10;

// We assign VR presentations to groups with a bitmask.
// Currently, we will only display either content or chrome.
Expand Down Expand Up @@ -364,7 +364,8 @@ enum class VRLayerTextureType : uint16_t {
LayerTextureType_None = 0,
LayerTextureType_D3D10SurfaceDescriptor = 1,
LayerTextureType_MacIOSurface = 2,
LayerTextureType_GeckoSurfaceTexture = 3
LayerTextureType_GeckoSurfaceTexture = 3,
LayerTextureType_ExternalVRSurface = 4
};

struct VRLayer_2D_Content {
Expand Down
71 changes: 61 additions & 10 deletions app/src/oculusvr/cpp/DeviceDelegateOculusVR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,8 @@ const vrb::Vector kAverageHeight(0.0f, 1.7f, 0.0f);
const vrb::Vector kAverageOculusHeight(0.0f, 1.65f, 0.0f);

struct DeviceDelegateOculusVR::State {
const static uint32_t EXTERNAL_SURFACE_BUFFER_SIZE = 2;

struct ControllerState {
const int32_t index;
const ElbowModel::HandEnum hand;
Expand Down Expand Up @@ -657,6 +659,7 @@ struct DeviceDelegateOculusVR::State {
ovrJava java = {};
ovrMobile* ovr = nullptr;
OculusEyeSwapChainPtr eyeSwapChains[VRAPI_EYE_COUNT];
ovrTextureSwapChain* eyeSurfaceSwapChain[EXTERNAL_SURFACE_BUFFER_SIZE];
OculusLayerCubePtr cubeLayer;
OculusLayerEquirectPtr equirectLayer;
std::vector<OculusLayerPtr> uiLayers;
Expand Down Expand Up @@ -719,6 +722,9 @@ struct DeviceDelegateOculusVR::State {
exit(status);
return;
}
for (int i = 0; i < EXTERNAL_SURFACE_BUFFER_SIZE; ++i) {
eyeSurfaceSwapChain[i] = nullptr;
}
initialized = true;
SetRenderSize(device::RenderMode::StandAlone);

Expand Down Expand Up @@ -1352,8 +1358,6 @@ DeviceDelegateOculusVR::StartFrame() {
ovrMatrix4f matrix = vrapi_GetTransformFromPose(&m.predictedTracking.HeadPose.Pose);
vrb::Matrix head = vrb::Matrix::FromRowMajor(matrix.M[0]);



if (m.renderMode == device::RenderMode::StandAlone) {
head.TranslateInPlace(kAverageHeight);
}
Expand All @@ -1371,6 +1375,20 @@ DeviceDelegateOculusVR::StartFrame() {
caps |= device::PositionEmulated;
}
m.immersiveDisplay->SetCapabilityFlags(caps);

uint32_t width, height;
m.GetImmersiveRenderSize(width, height);
for (int i = 0; i < DeviceDelegateOculusVR::State::EXTERNAL_SURFACE_BUFFER_SIZE; ++i) {
if (!m.eyeSurfaceSwapChain[i]) {
m.eyeSurfaceSwapChain[i] = vrapi_CreateAndroidSurfaceSwapChain(width, height);
auto surfaceOut = vrapi_GetTextureSwapChainAndroidSurface(m.eyeSurfaceSwapChain[i]);
surfaceOut = m.java.Env->NewGlobalRef(surfaceOut);
VRBrowser::SetExternalVRSurface(i, surfaceOut);
VRB_LOG("Creating AndroidSurface %d in DeviceDelegateOculusVR.", i);
}
}
VRBrowser::SetExternalVRSurfaceLength(State::EXTERNAL_SURFACE_BUFFER_SIZE);
VRBrowser::SetExternalVRSurfaceId(externalSurfaceId);
}

int lastReorientCount = m.reorientCount;
Expand Down Expand Up @@ -1470,13 +1488,33 @@ DeviceDelegateOculusVR::EndFrame(const bool aDiscard) {
projection.HeadPose = m.predictedTracking.HeadPose;
projection.Header.SrcBlend = VRAPI_FRAME_LAYER_BLEND_ONE;
projection.Header.DstBlend = VRAPI_FRAME_LAYER_BLEND_ONE_MINUS_SRC_ALPHA;
for (int i = 0; i < VRAPI_FRAME_LAYER_EYE_MAX; ++i) {
const auto &eyeSwapChain = m.eyeSwapChains[i];
const int swapChainIndex = m.frameIndex % eyeSwapChain->swapChainLength;
// Set up OVR layer textures
projection.Textures[i].ColorSwapChain = eyeSwapChain->ovrSwapChain;
projection.Textures[i].SwapChainIndex = swapChainIndex;
projection.Textures[i].TexCoordsFromTanAngles = ovrMatrix4f_TanAngleMatrixFromProjection(&projectionMatrix);

if (!enableExternalSurfaceRender) {
for (int i = 0; i < VRAPI_FRAME_LAYER_EYE_MAX; ++i) {
const auto &eyeSwapChain = m.eyeSwapChains[i];
const int swapChainIndex = m.frameIndex % eyeSwapChain->swapChainLength;
// Set up OVR layer textures
projection.Textures[i].ColorSwapChain = eyeSwapChain->ovrSwapChain;
projection.Textures[i].SwapChainIndex = swapChainIndex;
projection.Textures[i].TexCoordsFromTanAngles = ovrMatrix4f_TanAngleMatrixFromProjection(&projectionMatrix);
}
} else {
const int swapChainIndex = externalSurfaceId;
ovrMatrix4f proj(projectionMatrix);
// Flip texCoord in vertical when using WebGL frame textures.
proj.M[1][1] *= -1;
proj = ovrMatrix4f_TanAngleMatrixFromProjection(&proj);

for (int i = 0; i < VRAPI_FRAME_LAYER_EYE_MAX; ++i) {
const auto eyeSwapChain = m.eyeSurfaceSwapChain[swapChainIndex];
// Set up OVR layer textures
projection.Textures[i].ColorSwapChain = eyeSwapChain;
projection.Textures[i].SwapChainIndex = 0;
projection.Textures[i].TexCoordsFromTanAngles = proj;
}

// Switch to the next surface.
externalSurfaceId = (++externalSurfaceId) % State::EXTERNAL_SURFACE_BUFFER_SIZE;
}
layers[layerCount++] = &projection.Header;

Expand Down Expand Up @@ -1506,6 +1544,11 @@ DeviceDelegateOculusVR::EndFrame(const bool aDiscard) {
vrapi_SubmitFrame2(m.ovr, &frameDesc);
}

void
DeviceDelegateOculusVR::EnableExternalSurfaceRender(bool aEnable) {
enableExternalSurfaceRender = aEnable;
}

VRLayerQuadPtr
DeviceDelegateOculusVR::CreateLayerQuad(int32_t aWidth, int32_t aHeight,
VRLayerSurface::SurfaceType aSurfaceType) {
Expand Down Expand Up @@ -1689,6 +1732,13 @@ DeviceDelegateOculusVR::LeaveVR() {
for (int i = 0; i < VRAPI_EYE_COUNT; ++i) {
m.eyeSwapChains[i]->Destroy();
}
for (int i = 0; i < DeviceDelegateOculusVR::State::EXTERNAL_SURFACE_BUFFER_SIZE; ++i) {
if (m.eyeSurfaceSwapChain[i]) {
vrapi_DestroyTextureSwapChain(m.eyeSurfaceSwapChain[i]);
m.eyeSurfaceSwapChain[i] = nullptr;
VRBrowser::ReleaseExternalVRSurfaces();
}
}
if (m.cubeLayer) {
m.cubeLayer->Destroy();
}
Expand Down Expand Up @@ -1716,7 +1766,8 @@ DeviceDelegateOculusVR::ExitApp() {
return true;
}

DeviceDelegateOculusVR::DeviceDelegateOculusVR(State &aState) : m(aState) {}
DeviceDelegateOculusVR::DeviceDelegateOculusVR(State &aState) : m(aState),
externalSurfaceId(0), enableExternalSurfaceRender(false) {}

DeviceDelegateOculusVR::~DeviceDelegateOculusVR() { m.Shutdown(); }

Expand Down
3 changes: 3 additions & 0 deletions app/src/oculusvr/cpp/DeviceDelegateOculusVR.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class DeviceDelegateOculusVR : public DeviceDelegate {
void StartFrame() override;
void BindEye(const device::Eye aWhich) override;
void EndFrame(const bool aDiscard) override;
void EnableExternalSurfaceRender(bool aEnable) override;
VRLayerQuadPtr CreateLayerQuad(int32_t aWidth, int32_t aHeight,
VRLayerSurface::SurfaceType aSurfaceType) override;
VRLayerQuadPtr CreateLayerQuad(const VRLayerSurfacePtr& aMoveLayer) override;
Expand All @@ -65,6 +66,8 @@ class DeviceDelegateOculusVR : public DeviceDelegate {
virtual ~DeviceDelegateOculusVR();
private:
State& m;
int32_t externalSurfaceId;
bool enableExternalSurfaceRender;
VRB_NO_DEFAULTS(DeviceDelegateOculusVR)
};

Expand Down

0 comments on commit 94fe049

Please sign in to comment.