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

Commit 94fe049

Browse files
committed
Using Surface from swap chains to render immersive frames instead of framebuffer textures.
1 parent 845e99b commit 94fe049

File tree

11 files changed

+160
-21
lines changed

11 files changed

+160
-21
lines changed

app/src/common/shared/org/mozilla/vrbrowser/VRBrowserActivity.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,25 @@ public void dismiss() {
951951
});
952952
}
953953

954+
public void setExternalVRSurfaceLength(int aLen) {
955+
GeckoVRManager.setExternalSurfaceLength(aLen);
956+
}
957+
958+
public void setExternalVRSurfaceIndex(int aIndex) {
959+
GeckoVRManager.setExternalSurfaceIndex(aIndex);
960+
}
961+
962+
public void setExternalVRSurface(int aIndex, Surface aSurface) {
963+
if (aSurface == null) {
964+
Log.e(LOGTAG, "aSurface is null in setExternalVRSurface...");
965+
}
966+
GeckoVRManager.insertExternalSurface(aIndex, aSurface);
967+
}
968+
969+
public void releaseExternalVRSurfaces() {
970+
GeckoVRManager.releaseExternalSurfaces();
971+
}
972+
954973
void createOffscreenDisplay() {
955974
int[] ids = new int[1];
956975
GLES20.glGenTextures(1, ids, 0);

app/src/common/shared/org/mozilla/vrbrowser/browser/engine/SessionUtils.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.mozilla.gecko.GeckoProfile;
1111
import org.mozilla.vrbrowser.BuildConfig;
1212
import org.mozilla.vrbrowser.browser.SettingsStore;
13+
import org.mozilla.vrbrowser.utils.DeviceType;
1314

1415
import java.io.File;
1516
import java.io.FileNotFoundException;
@@ -55,6 +56,12 @@ public static void vrPrefsWorkAround(Context aContext, Bundle aExtras) {
5556
out.write("pref(\"media.autoplay.enabled.ask-permission\", false);\n".getBytes());
5657
out.write("pref(\"media.autoplay.default\", 0);\n".getBytes());
5758
}
59+
// In Oculus platform, we can render WebGL immersive frames info AndroidSurface.
60+
if (DeviceType.isOculusBuild()) {
61+
out.write("pref(\"webgl.enable-externalvr-surface\", true);\n".getBytes());
62+
} else {
63+
out.write("pref(\"webgl.enable-externalvr-surface\", false);\n".getBytes());
64+
}
5865
} catch (FileNotFoundException e) {
5966
Log.e(LOGTAG, "Unable to create file: '" + prefFileName + "' got exception: " + e.toString());
6067
} catch (IOException e) {

app/src/main/cpp/BrowserWorld.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,6 +1190,7 @@ void
11901190
BrowserWorld::DrawWorld() {
11911191
m.externalVR->SetCompositorEnabled(true);
11921192
m.device->SetRenderMode(device::RenderMode::StandAlone);
1193+
m.device->EnableExternalSurfaceRender(false);
11931194
if (m.fadeAnimation) {
11941195
m.fadeAnimation->UpdateAnimation();
11951196
}
@@ -1257,23 +1258,29 @@ BrowserWorld::DrawImmersive() {
12571258
m.device->StartFrame();
12581259
VRB_GL_CHECK(glDepthMask(GL_FALSE));
12591260
m.externalVR->PushFramePoses(m.device->GetHeadTransform(), m.controllers->GetControllers(), m.context->GetTimestamp());
1261+
mozilla::gfx::VRLayerTextureType surfaceType;
12601262
int32_t surfaceHandle, textureWidth, textureHeight = 0;
12611263
device::EyeRect leftEye, rightEye;
12621264
bool aDiscardFrame = !m.externalVR->WaitFrameResult();
1263-
m.externalVR->GetFrameResult(surfaceHandle, textureWidth, textureHeight, leftEye, rightEye);
1265+
m.externalVR->GetFrameResult(surfaceType, surfaceHandle, textureWidth, textureHeight, leftEye, rightEye);
12641266
ExternalVR::VRState state = m.externalVR->GetVRState();
12651267
if (state == ExternalVR::VRState::Rendering) {
12661268
if (!aDiscardFrame) {
12671269
if (textureWidth > 0 && textureHeight > 0) {
12681270
m.device->SetImmersiveSize((uint32_t) textureWidth/2, (uint32_t) textureHeight);
12691271
}
1270-
m.blitter->StartFrame(surfaceHandle, leftEye, rightEye);
1271-
m.device->BindEye(device::Eye::Left);
1272-
m.blitter->Draw(device::Eye::Left);
1272+
m.device->EnableExternalSurfaceRender(surfaceType ==
1273+
mozilla::gfx::VRLayerTextureType::LayerTextureType_ExternalVRSurface);
1274+
// In Oculus platform, we can render WebGL immersive frames info AndroidSurface.
1275+
if (surfaceType != mozilla::gfx::VRLayerTextureType::LayerTextureType_ExternalVRSurface) {
1276+
m.blitter->StartFrame(surfaceHandle, leftEye, rightEye);
1277+
m.device->BindEye(device::Eye::Left);
1278+
m.blitter->Draw(device::Eye::Left);
12731279
#if !defined(VRBROWSER_NO_VR_API)
1274-
m.device->BindEye(device::Eye::Right);
1275-
m.blitter->Draw(device::Eye::Right);
1280+
m.device->BindEye(device::Eye::Right);
1281+
m.blitter->Draw(device::Eye::Right);
12761282
#endif // !defined(VRBROWSER_NO_VR_API)
1283+
}
12771284
}
12781285
m.device->EndFrame(aDiscardFrame);
12791286
m.blitter->EndFrame();

app/src/main/cpp/DeviceDelegate.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class DeviceDelegate {
6767
virtual void StartFrame() = 0;
6868
virtual void BindEye(const device::Eye aWhich) = 0;
6969
virtual void EndFrame(bool aDiscard = false) = 0;
70+
virtual void EnableExternalSurfaceRender(bool aEnable) {}
7071
virtual VRLayerQuadPtr CreateLayerQuad(int32_t aWidth, int32_t aHeight,
7172
VRLayerSurface::SurfaceType aSurfaceType) { return nullptr; }
7273
virtual VRLayerQuadPtr CreateLayerQuad(const VRLayerSurfacePtr& aMoveLayer) { return nullptr; }

app/src/main/cpp/ExternalVR.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -476,10 +476,10 @@ ExternalVR::CompleteEnumeration()
476476
m.system.enumerationCompleted = true;
477477
}
478478

479-
480479
void
481-
ExternalVR::GetFrameResult(int32_t& aSurfaceHandle, int32_t& aTextureWidth, int32_t& aTextureHeight,
480+
ExternalVR::GetFrameResult(mozilla::gfx::VRLayerTextureType& aSurfaceType, int32_t& aSurfaceHandle, int32_t& aTextureWidth, int32_t& aTextureHeight,
482481
device::EyeRect& aLeftEye, device::EyeRect& aRightEye) const {
482+
aSurfaceType = m.browser.layerState[0].layer_stereo_immersive.textureType;
483483
aSurfaceHandle = (int32_t)m.browser.layerState[0].layer_stereo_immersive.textureHandle;
484484
mozilla::gfx::VRLayerEyeRect& left = m.browser.layerState[0].layer_stereo_immersive.leftEyeRect;
485485
mozilla::gfx::VRLayerEyeRect& right = m.browser.layerState[0].layer_stereo_immersive.rightEyeRect;

app/src/main/cpp/ExternalVR.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "Controller.h"
1111
#include "DeviceDelegate.h"
1212
#include "Device.h"
13+
#include "moz_external_vr.h"
1314
#include <memory>
1415
#include <string>
1516
#include <vector>
@@ -54,7 +55,8 @@ class ExternalVR : public ImmersiveDisplay {
5455
VRState GetVRState() const;
5556
void PushFramePoses(const vrb::Matrix& aHeadTransform, const std::vector<Controller>& aControllers, const double aTimestamp);
5657
bool WaitFrameResult();
57-
void GetFrameResult(int32_t& aSurfaceHandle,
58+
void GetFrameResult(mozilla::gfx::VRLayerTextureType& aSurfaceType,
59+
int32_t& aSurfaceHandle,
5860
int32_t& aTextureWidth,
5961
int32_t& aTextureHeight,
6062
device::EyeRect& aLeftEye,

app/src/main/cpp/VRBrowser.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@ const char* kHaltActivity = "haltActivity";
5252
const char* kHaltActivitySignature = "(I)V";
5353
const char* kHandlePoorPerformance = "handlePoorPerformance";
5454
const char* kHandlePoorPerformanceSignature = "()V";
55+
const char* kSetExternalVRSurfaceLength = "setExternalVRSurfaceLength";
56+
const char* kSetExternalVRSurfaceLengthSignature = "(I)V";
57+
const char* kSetExternalVRSurfaceIndex = "setExternalVRSurfaceIndex";
58+
const char* kSetExternalVRSurfaceIndexSignature = "(I)V";
59+
const char* kSetExternalVRSurface = "setExternalVRSurface";
60+
const char* kSetExternalVRSurfaceSignature = "(ILandroid/view/Surface;)V";
61+
const char* kReleaseExternalSurfaces = "releaseExternalVRSurfaces";
62+
const char* kReleaseExternalSurfacesSignature = "()V";
5563

5664
JNIEnv* sEnv = nullptr;
5765
jclass sBrowserClass = nullptr;
@@ -77,6 +85,10 @@ jmethodID sAreLayersEnabled = nullptr;
7785
jmethodID sSetDeviceType = nullptr;
7886
jmethodID sHaltActivity = nullptr;
7987
jmethodID sHandlePoorPerformance = nullptr;
88+
jmethodID sSetExternalVRSurfaceLength = nullptr;
89+
jmethodID sSetExternalVRSurfaceIndex = nullptr;
90+
jmethodID sSetExternalVRSurface = nullptr;
91+
jmethodID sReleaseExternalSurfaces = nullptr;
8092
}
8193

8294
namespace crow {
@@ -117,6 +129,10 @@ VRBrowser::InitializeJava(JNIEnv* aEnv, jobject aActivity) {
117129
sSetDeviceType = FindJNIMethodID(sEnv, sBrowserClass, kSetDeviceType, kSetDeviceTypeSignature);
118130
sHaltActivity = FindJNIMethodID(sEnv, sBrowserClass, kHaltActivity, kHaltActivitySignature);
119131
sHandlePoorPerformance = FindJNIMethodID(sEnv, sBrowserClass, kHandlePoorPerformance, kHandlePoorPerformanceSignature);
132+
sSetExternalVRSurface = FindJNIMethodID(sEnv, sBrowserClass, kSetExternalVRSurface, kSetExternalVRSurfaceSignature);
133+
sSetExternalVRSurfaceLength = FindJNIMethodID(sEnv, sBrowserClass, kSetExternalVRSurfaceLength, kSetExternalVRSurfaceLengthSignature);
134+
sSetExternalVRSurfaceIndex = FindJNIMethodID(sEnv, sBrowserClass, kSetExternalVRSurfaceIndex, kSetExternalVRSurfaceIndexSignature);
135+
sReleaseExternalSurfaces = FindJNIMethodID(sEnv, sBrowserClass, kReleaseExternalSurfaces, kReleaseExternalSurfacesSignature);
120136
}
121137

122138
void
@@ -151,6 +167,7 @@ VRBrowser::ShutdownJava() {
151167
sAreLayersEnabled = nullptr;
152168
sSetDeviceType = nullptr;
153169
sHaltActivity = nullptr;
170+
sSetExternalVRSurface = nullptr;
154171
sEnv = nullptr;
155172
}
156173

@@ -339,4 +356,31 @@ VRBrowser::HandlePoorPerformance() {
339356
CheckJNIException(sEnv, __FUNCTION__);
340357
}
341358

359+
void
360+
VRBrowser::SetExternalVRSurfaceLength(jint aLen) {
361+
if (!ValidateMethodID(sEnv, sActivity, sSetExternalVRSurfaceLength, __FUNCTION__)) { return; }
362+
sEnv->CallVoidMethod(sActivity, sSetExternalVRSurfaceLength, aLen);
363+
CheckJNIException(sEnv, __FUNCTION__);
364+
}
365+
366+
void
367+
VRBrowser::SetExternalVRSurfaceId(jint aId) {
368+
if (!ValidateMethodID(sEnv, sActivity, sSetExternalVRSurfaceIndex, __FUNCTION__)) { return; }
369+
sEnv->CallVoidMethod(sActivity, sSetExternalVRSurfaceIndex, aId);
370+
CheckJNIException(sEnv, __FUNCTION__);
371+
}
372+
373+
void
374+
VRBrowser::SetExternalVRSurface(jint aIndex, jobject aSurface) {
375+
if (!ValidateMethodID(sEnv, sActivity, sSetExternalVRSurface, __FUNCTION__)) { return; }
376+
sEnv->CallVoidMethod(sActivity, sSetExternalVRSurface, aIndex, aSurface);
377+
CheckJNIException(sEnv, __FUNCTION__);
378+
}
379+
380+
void
381+
VRBrowser::ReleaseExternalVRSurfaces() {
382+
if (!ValidateMethodID(sEnv, sActivity, sReleaseExternalSurfaces, __FUNCTION__)) { return; }
383+
sEnv->CallVoidMethod(sActivity, sReleaseExternalSurfaces);
384+
CheckJNIException(sEnv, __FUNCTION__);
385+
}
342386
} // namespace crow

app/src/main/cpp/VRBrowser.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ bool AreLayersEnabled();
3939
void SetDeviceType(const jint aType);
4040
void HaltActivity(const jint aReason);
4141
void HandlePoorPerformance();
42+
void SetExternalVRSurfaceLength(jint aLen);
43+
void SetExternalVRSurfaceId(jint aId);
44+
void SetExternalVRSurface(jint aIndex, jobject aSurface);
45+
void ReleaseExternalVRSurfaces();
4246
} // namespace VRBrowser;
4347

4448
} // namespace crow

app/src/main/cpp/moz_external_vr.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ enum class GamepadCapabilityFlags : uint16_t;
4040
#endif // MOZILLA_INTERNAL_API
4141
namespace gfx {
4242

43-
static const int32_t kVRExternalVersion = 9;
43+
static const int32_t kVRExternalVersion = 10;
4444

4545
// We assign VR presentations to groups with a bitmask.
4646
// Currently, we will only display either content or chrome.
@@ -364,7 +364,8 @@ enum class VRLayerTextureType : uint16_t {
364364
LayerTextureType_None = 0,
365365
LayerTextureType_D3D10SurfaceDescriptor = 1,
366366
LayerTextureType_MacIOSurface = 2,
367-
LayerTextureType_GeckoSurfaceTexture = 3
367+
LayerTextureType_GeckoSurfaceTexture = 3,
368+
LayerTextureType_ExternalVRSurface = 4
368369
};
369370

370371
struct VRLayer_2D_Content {

app/src/oculusvr/cpp/DeviceDelegateOculusVR.cpp

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,8 @@ const vrb::Vector kAverageHeight(0.0f, 1.7f, 0.0f);
629629
const vrb::Vector kAverageOculusHeight(0.0f, 1.65f, 0.0f);
630630

631631
struct DeviceDelegateOculusVR::State {
632+
const static uint32_t EXTERNAL_SURFACE_BUFFER_SIZE = 2;
633+
632634
struct ControllerState {
633635
const int32_t index;
634636
const ElbowModel::HandEnum hand;
@@ -657,6 +659,7 @@ struct DeviceDelegateOculusVR::State {
657659
ovrJava java = {};
658660
ovrMobile* ovr = nullptr;
659661
OculusEyeSwapChainPtr eyeSwapChains[VRAPI_EYE_COUNT];
662+
ovrTextureSwapChain* eyeSurfaceSwapChain[EXTERNAL_SURFACE_BUFFER_SIZE];
660663
OculusLayerCubePtr cubeLayer;
661664
OculusLayerEquirectPtr equirectLayer;
662665
std::vector<OculusLayerPtr> uiLayers;
@@ -719,6 +722,9 @@ struct DeviceDelegateOculusVR::State {
719722
exit(status);
720723
return;
721724
}
725+
for (int i = 0; i < EXTERNAL_SURFACE_BUFFER_SIZE; ++i) {
726+
eyeSurfaceSwapChain[i] = nullptr;
727+
}
722728
initialized = true;
723729
SetRenderSize(device::RenderMode::StandAlone);
724730

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

1355-
1356-
13571361
if (m.renderMode == device::RenderMode::StandAlone) {
13581362
head.TranslateInPlace(kAverageHeight);
13591363
}
@@ -1371,6 +1375,20 @@ DeviceDelegateOculusVR::StartFrame() {
13711375
caps |= device::PositionEmulated;
13721376
}
13731377
m.immersiveDisplay->SetCapabilityFlags(caps);
1378+
1379+
uint32_t width, height;
1380+
m.GetImmersiveRenderSize(width, height);
1381+
for (int i = 0; i < DeviceDelegateOculusVR::State::EXTERNAL_SURFACE_BUFFER_SIZE; ++i) {
1382+
if (!m.eyeSurfaceSwapChain[i]) {
1383+
m.eyeSurfaceSwapChain[i] = vrapi_CreateAndroidSurfaceSwapChain(width, height);
1384+
auto surfaceOut = vrapi_GetTextureSwapChainAndroidSurface(m.eyeSurfaceSwapChain[i]);
1385+
surfaceOut = m.java.Env->NewGlobalRef(surfaceOut);
1386+
VRBrowser::SetExternalVRSurface(i, surfaceOut);
1387+
VRB_LOG("Creating AndroidSurface %d in DeviceDelegateOculusVR.", i);
1388+
}
1389+
}
1390+
VRBrowser::SetExternalVRSurfaceLength(State::EXTERNAL_SURFACE_BUFFER_SIZE);
1391+
VRBrowser::SetExternalVRSurfaceId(externalSurfaceId);
13741392
}
13751393

13761394
int lastReorientCount = m.reorientCount;
@@ -1470,13 +1488,33 @@ DeviceDelegateOculusVR::EndFrame(const bool aDiscard) {
14701488
projection.HeadPose = m.predictedTracking.HeadPose;
14711489
projection.Header.SrcBlend = VRAPI_FRAME_LAYER_BLEND_ONE;
14721490
projection.Header.DstBlend = VRAPI_FRAME_LAYER_BLEND_ONE_MINUS_SRC_ALPHA;
1473-
for (int i = 0; i < VRAPI_FRAME_LAYER_EYE_MAX; ++i) {
1474-
const auto &eyeSwapChain = m.eyeSwapChains[i];
1475-
const int swapChainIndex = m.frameIndex % eyeSwapChain->swapChainLength;
1476-
// Set up OVR layer textures
1477-
projection.Textures[i].ColorSwapChain = eyeSwapChain->ovrSwapChain;
1478-
projection.Textures[i].SwapChainIndex = swapChainIndex;
1479-
projection.Textures[i].TexCoordsFromTanAngles = ovrMatrix4f_TanAngleMatrixFromProjection(&projectionMatrix);
1491+
1492+
if (!enableExternalSurfaceRender) {
1493+
for (int i = 0; i < VRAPI_FRAME_LAYER_EYE_MAX; ++i) {
1494+
const auto &eyeSwapChain = m.eyeSwapChains[i];
1495+
const int swapChainIndex = m.frameIndex % eyeSwapChain->swapChainLength;
1496+
// Set up OVR layer textures
1497+
projection.Textures[i].ColorSwapChain = eyeSwapChain->ovrSwapChain;
1498+
projection.Textures[i].SwapChainIndex = swapChainIndex;
1499+
projection.Textures[i].TexCoordsFromTanAngles = ovrMatrix4f_TanAngleMatrixFromProjection(&projectionMatrix);
1500+
}
1501+
} else {
1502+
const int swapChainIndex = externalSurfaceId;
1503+
ovrMatrix4f proj(projectionMatrix);
1504+
// Flip texCoord in vertical when using WebGL frame textures.
1505+
proj.M[1][1] *= -1;
1506+
proj = ovrMatrix4f_TanAngleMatrixFromProjection(&proj);
1507+
1508+
for (int i = 0; i < VRAPI_FRAME_LAYER_EYE_MAX; ++i) {
1509+
const auto eyeSwapChain = m.eyeSurfaceSwapChain[swapChainIndex];
1510+
// Set up OVR layer textures
1511+
projection.Textures[i].ColorSwapChain = eyeSwapChain;
1512+
projection.Textures[i].SwapChainIndex = 0;
1513+
projection.Textures[i].TexCoordsFromTanAngles = proj;
1514+
}
1515+
1516+
// Switch to the next surface.
1517+
externalSurfaceId = (++externalSurfaceId) % State::EXTERNAL_SURFACE_BUFFER_SIZE;
14801518
}
14811519
layers[layerCount++] = &projection.Header;
14821520

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

1547+
void
1548+
DeviceDelegateOculusVR::EnableExternalSurfaceRender(bool aEnable) {
1549+
enableExternalSurfaceRender = aEnable;
1550+
}
1551+
15091552
VRLayerQuadPtr
15101553
DeviceDelegateOculusVR::CreateLayerQuad(int32_t aWidth, int32_t aHeight,
15111554
VRLayerSurface::SurfaceType aSurfaceType) {
@@ -1689,6 +1732,13 @@ DeviceDelegateOculusVR::LeaveVR() {
16891732
for (int i = 0; i < VRAPI_EYE_COUNT; ++i) {
16901733
m.eyeSwapChains[i]->Destroy();
16911734
}
1735+
for (int i = 0; i < DeviceDelegateOculusVR::State::EXTERNAL_SURFACE_BUFFER_SIZE; ++i) {
1736+
if (m.eyeSurfaceSwapChain[i]) {
1737+
vrapi_DestroyTextureSwapChain(m.eyeSurfaceSwapChain[i]);
1738+
m.eyeSurfaceSwapChain[i] = nullptr;
1739+
VRBrowser::ReleaseExternalVRSurfaces();
1740+
}
1741+
}
16921742
if (m.cubeLayer) {
16931743
m.cubeLayer->Destroy();
16941744
}
@@ -1716,7 +1766,8 @@ DeviceDelegateOculusVR::ExitApp() {
17161766
return true;
17171767
}
17181768

1719-
DeviceDelegateOculusVR::DeviceDelegateOculusVR(State &aState) : m(aState) {}
1769+
DeviceDelegateOculusVR::DeviceDelegateOculusVR(State &aState) : m(aState),
1770+
externalSurfaceId(0), enableExternalSurfaceRender(false) {}
17201771

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

0 commit comments

Comments
 (0)