diff --git a/Common/GPU/OpenGL/GLCommon.h b/Common/GPU/OpenGL/GLCommon.h index 26f9220d7f..126f4311be 100644 --- a/Common/GPU/OpenGL/GLCommon.h +++ b/Common/GPU/OpenGL/GLCommon.h @@ -5,6 +5,9 @@ #if PPSSPP_PLATFORM(IOS) #include #include +#elif defined(OPEXR) +#include +#include #elif defined(USING_GLES2) #include #include diff --git a/Common/GPU/OpenGL/GLRenderManager.cpp b/Common/GPU/OpenGL/GLRenderManager.cpp index c9897232d6..b5f5252b95 100644 --- a/Common/GPU/OpenGL/GLRenderManager.cpp +++ b/Common/GPU/OpenGL/GLRenderManager.cpp @@ -203,22 +203,6 @@ bool GLRenderManager::ThreadFrame() { std::unique_lock lock(mutex_); if (!run_) return false; -#ifdef OPENXR - VR_BeginFrame(VR_GetEngine()); - - // Decide if the scene is 3D or not - if (g_Config.bEnableVR && !VR_GetConfig(VR_CONFIG_FORCE_2D) && (VR_GetConfig(VR_CONFIG_3D_GEOMETRY_COUNT) > 15)) { - VR_SetConfig(VR_CONFIG_MODE, g_Config.bEnableStereo ? VR_MODE_STEREO_6DOF : VR_MODE_MONO_6DOF); - } else { - VR_SetConfig(VR_CONFIG_MODE, VR_MODE_FLAT_SCREEN); - } - VR_SetConfig(VR_CONFIG_3D_GEOMETRY_COUNT, VR_GetConfig(VR_CONFIG_3D_GEOMETRY_COUNT) / 2); - - // Set customizations - VR_SetConfig(VR_CONFIG_6DOF_ENABLED, g_Config.bEnable6DoF); - VR_SetConfig(VR_CONFIG_CANVAS_DISTANCE, g_Config.iCanvasDistance); - VR_SetConfig(VR_CONFIG_FOV_SCALE, g_Config.iFieldOfViewPercentage); -#endif // In case of syncs or other partial completion, we keep going until we complete a frame. do { @@ -254,12 +238,33 @@ bool GLRenderManager::ThreadFrame() { INFO_LOG(G3D, "Running first frame (%d)", threadFrame_); firstFrame = false; } + +#ifdef OPENXR + if (VR_BeginFrame(VR_GetEngine())) { + + // Decide if the scene is 3D or not + if (g_Config.bEnableVR && !VR_GetConfig(VR_CONFIG_FORCE_2D) && (VR_GetConfig(VR_CONFIG_3D_GEOMETRY_COUNT) > 15)) { + VR_SetConfig(VR_CONFIG_MODE, g_Config.bEnableStereo ? VR_MODE_STEREO_6DOF : VR_MODE_MONO_6DOF); + } else { + VR_SetConfig(VR_CONFIG_MODE, VR_MODE_FLAT_SCREEN); + } + VR_SetConfig(VR_CONFIG_3D_GEOMETRY_COUNT, VR_GetConfig(VR_CONFIG_3D_GEOMETRY_COUNT) / 2); + + // Set customizations + VR_SetConfig(VR_CONFIG_6DOF_ENABLED, g_Config.bEnable6DoF); + VR_SetConfig(VR_CONFIG_CANVAS_DISTANCE, g_Config.iCanvasDistance); + VR_SetConfig(VR_CONFIG_FOV_SCALE, g_Config.iFieldOfViewPercentage); + + // Render scene + Run(threadFrame_); + VR_EndFrame(VR_GetEngine()); + } +#else Run(threadFrame_); +#endif VLOG("PULL: Finished frame %d", threadFrame_); } while (!nextFrame); -#ifdef OPENXR - VR_EndFrame(VR_GetEngine()); -#endif + return true; } diff --git a/Common/VR/VRBase.h b/Common/VR/VRBase.h index 5cf71636ed..ae7fb7fcd3 100644 --- a/Common/VR/VRBase.h +++ b/Common/VR/VRBase.h @@ -97,6 +97,7 @@ typedef struct { XrSwapchainImageOpenGLESKHR* ColorSwapChainImage; XrSwapchainImageOpenGLESKHR* DepthSwapChainImage; unsigned int* FrameBuffers; + bool Acquired; } ovrFramebuffer; typedef struct { diff --git a/Common/VR/VRFramebuffer.cpp b/Common/VR/VRFramebuffer.cpp index 3506fc0dce..81e40ec3d8 100644 --- a/Common/VR/VRFramebuffer.cpp +++ b/Common/VR/VRFramebuffer.cpp @@ -38,6 +38,7 @@ void ovrFramebuffer_Clear(ovrFramebuffer* frameBuffer) { frameBuffer->DepthSwapChain.Height = 0; frameBuffer->FrameBuffers = NULL; + frameBuffer->Acquired = false; } bool ovrFramebuffer_Create( @@ -185,11 +186,15 @@ void ovrFramebuffer_Acquire(ovrFramebuffer* frameBuffer) { i, waitInfo.timeout * (1E-9)); } + frameBuffer->Acquired = res == XR_SUCCESS; } void ovrFramebuffer_Release(ovrFramebuffer* frameBuffer) { - XrSwapchainImageReleaseInfo releaseInfo = {XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO, NULL}; - OXR(xrReleaseSwapchainImage(frameBuffer->ColorSwapChain.Handle, &releaseInfo)); + if (frameBuffer->Acquired) { + XrSwapchainImageReleaseInfo releaseInfo = {XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO, NULL}; + OXR(xrReleaseSwapchainImage(frameBuffer->ColorSwapChain.Handle, &releaseInfo)); + frameBuffer->Acquired = false; + } } /* diff --git a/Common/VR/VRRenderer.cpp b/Common/VR/VRRenderer.cpp index 97975d72c4..db35501a3b 100644 --- a/Common/VR/VRRenderer.cpp +++ b/Common/VR/VRRenderer.cpp @@ -232,7 +232,7 @@ void VR_ClearFrameBuffer( int width, int height) { glEnable( GL_SCISSOR_TEST ); glViewport( 0, 0, width, height ); - glClearColor( 0.0f, 0.5f, 1.0f, 1.0f ); + glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); glScissor( 0, 0, width, height ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); @@ -241,13 +241,13 @@ void VR_ClearFrameBuffer( int width, int height) { glDisable( GL_SCISSOR_TEST ); } -void VR_BeginFrame( engine_t* engine ) { +bool VR_BeginFrame( engine_t* engine ) { GLboolean stageBoundsDirty = GL_TRUE; if (ovrApp_HandleXrEvents(&engine->appState)) { VR_Recenter(engine); } if (engine->appState.SessionActive == GL_FALSE) { - return; + return false; } if (stageBoundsDirty) { @@ -267,7 +267,7 @@ void VR_BeginFrame( engine_t* engine ) { OXR(xrWaitFrame(engine->appState.Session, &waitFrameInfo, &frameState)); engine->predictedDisplayTime = frameState.predictedDisplayTime; if (!frameState.shouldRender) { - return; + return false; } // Get the HMD pose, predicted for the middle of the time period during which @@ -315,11 +315,13 @@ void VR_BeginFrame( engine_t* engine ) { ovrFramebuffer_Acquire(frameBuffer); ovrFramebuffer_SetCurrent(frameBuffer); VR_ClearFrameBuffer(frameBuffer->ColorSwapChain.Width, frameBuffer->ColorSwapChain.Height); + return true; } void VR_EndFrame( engine_t* engine ) { // Clear the alpha channel, other way OpenXR would not transfer the framebuffer fully + VR_BindFramebuffer(engine); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); diff --git a/Common/VR/VRRenderer.h b/Common/VR/VRRenderer.h index a7ab247345..01905b15c9 100644 --- a/Common/VR/VRRenderer.h +++ b/Common/VR/VRRenderer.h @@ -38,7 +38,7 @@ void VR_GetResolution( engine_t* engine, int *pWidth, int *pHeight ); void VR_InitRenderer( engine_t* engine ); void VR_DestroyRenderer( engine_t* engine ); -void VR_BeginFrame( engine_t* engine ); +bool VR_BeginFrame( engine_t* engine ); void VR_EndFrame( engine_t* engine ); int VR_GetConfig( VRConfig config ); diff --git a/android/src/org/ppsspp/ppsspp/NativeActivity.java b/android/src/org/ppsspp/ppsspp/NativeActivity.java index bbdf045c82..758d7eb6a8 100644 --- a/android/src/org/ppsspp/ppsspp/NativeActivity.java +++ b/android/src/org/ppsspp/ppsspp/NativeActivity.java @@ -381,7 +381,7 @@ public abstract class NativeActivity extends Activity { } int deviceType = NativeApp.DEVICE_TYPE_MOBILE; - if (BuildConfig.FLAVOR.compareTo("quest") == 0) { + if (isVRDevice()) { deviceType = NativeApp.DEVICE_TYPE_VR; } UiModeManager uiModeManager = (UiModeManager) getSystemService(UI_MODE_SERVICE); @@ -621,7 +621,7 @@ public abstract class NativeActivity extends Activity { if (javaGL) { mGLSurfaceView = new NativeGLView(this); nativeRenderer = new NativeRenderer(this); - mGLSurfaceView.setEGLContextClientVersion(2); + mGLSurfaceView.setEGLContextClientVersion(isVRDevice() ? 3 : 2); sizeManager.setSurfaceView(mGLSurfaceView); // Setup the GLSurface and ask android for the correct @@ -1545,4 +1545,8 @@ public abstract class NativeActivity extends Activity { finish(); } } + + private boolean isVRDevice() { + return BuildConfig.FLAVOR.compareTo("quest") == 0; + } }