| 562 | }; |
| 563 | |
| 564 | System::Session::Frame::Frame(Session::Impl& sessionImpl) |
| 565 | : Views{ sessionImpl.RenderResources.ActiveFrameViews } |
| 566 | , InputSources{ sessionImpl.ActionResources.ActiveInputSources } |
| 567 | , m_impl{ std::make_unique<System::Session::Frame::Impl>(sessionImpl) } |
| 568 | { |
| 569 | auto session = m_impl->sessionImpl.Session; |
| 570 | |
| 571 | XrFrameWaitInfo frameWaitInfo{ XR_TYPE_FRAME_WAIT_INFO }; |
| 572 | XrFrameState frameState{ XR_TYPE_FRAME_STATE }; |
| 573 | XrCheck(xrWaitFrame(session, &frameWaitInfo, &frameState)); |
| 574 | m_impl->shouldRender = frameState.shouldRender; |
| 575 | m_impl->displayTime = frameState.predictedDisplayTime; |
| 576 | |
| 577 | XrFrameBeginInfo frameBeginInfo{ XR_TYPE_FRAME_BEGIN_INFO }; |
| 578 | XrCheck(xrBeginFrame(session, &frameBeginInfo)); |
| 579 | |
| 580 | auto& renderResources = m_impl->sessionImpl.RenderResources; |
| 581 | |
| 582 | // Only render when session is visible. otherwise submit zero layers |
| 583 | if (m_impl->shouldRender) |
| 584 | { |
| 585 | uint32_t viewCapacityInput = static_cast<uint32_t>(renderResources.Views.size()); |
| 586 | uint32_t viewCountOutput; |
| 587 | |
| 588 | XrViewState viewState{ XR_TYPE_VIEW_STATE }; |
| 589 | XrViewLocateInfo viewLocateInfo{ XR_TYPE_VIEW_LOCATE_INFO }; |
| 590 | viewLocateInfo.viewConfigurationType = System::Impl::VIEW_CONFIGURATION_TYPE; |
| 591 | viewLocateInfo.displayTime = m_impl->displayTime; |
| 592 | viewLocateInfo.space = m_impl->sessionImpl.SceneSpace; |
| 593 | XrCheck(xrLocateViews(session, &viewLocateInfo, &viewState, viewCapacityInput, &viewCountOutput, renderResources.Views.data())); |
| 594 | assert(viewCountOutput == viewCapacityInput); |
| 595 | assert(viewCountOutput == renderResources.ConfigViews.size()); |
| 596 | assert(viewCountOutput == renderResources.ColorSwapchains.size()); |
| 597 | assert(viewCountOutput == renderResources.DepthSwapchains.size()); |
| 598 | |
| 599 | renderResources.ProjectionLayerViews.resize(viewCountOutput); |
| 600 | if (m_impl->sessionImpl.HmdImpl.Extensions->DepthExtensionSupported) |
| 601 | { |
| 602 | renderResources.DepthInfoViews.resize(viewCountOutput); |
| 603 | } |
| 604 | |
| 605 | Views.resize(viewCountOutput); |
| 606 | |
| 607 | // Prepare rendering parameters of each view for swapchain texture arrays |
| 608 | for (uint32_t idx = 0; idx < viewCountOutput; ++idx) |
| 609 | { |
| 610 | const auto& colorSwapchain = renderResources.ColorSwapchains[idx]; |
| 611 | const auto& depthSwapchain = renderResources.DepthSwapchains[idx]; |
| 612 | |
| 613 | // Use the full range of recommended image size to achieve optimum resolution |
| 614 | const XrRect2Di imageRect = { {0, 0}, { colorSwapchain.Width, colorSwapchain.Height } }; |
| 615 | assert(colorSwapchain.Width == depthSwapchain.Width); |
| 616 | assert(colorSwapchain.Height == depthSwapchain.Height); |
| 617 | |
| 618 | const uint32_t colorSwapchainImageIndex = AquireAndWaitForSwapchainImage(colorSwapchain.Handle); |
| 619 | const uint32_t depthSwapchainImageIndex = AquireAndWaitForSwapchainImage(depthSwapchain.Handle); |
| 620 | |
| 621 | // Populate the struct that consuming code will use for rendering. |
nothing calls this directly
no test coverage detected