@@ -629,6 +629,8 @@ const vrb::Vector kAverageHeight(0.0f, 1.7f, 0.0f);
629629const vrb::Vector kAverageOculusHeight (0 .0f , 1 .65f , 0 .0f );
630630
631631struct 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+
15091552VRLayerQuadPtr
15101553DeviceDelegateOculusVR::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
17211772DeviceDelegateOculusVR::~DeviceDelegateOculusVR () { m.Shutdown (); }
17221773
0 commit comments