| 778 | } |
| 779 | |
| 780 | void Graphics::Present(void) |
| 781 | { |
| 782 | if (g_bEnableHDROutput) |
| 783 | PreparePresentHDR(); |
| 784 | else |
| 785 | PreparePresentLDR(); |
| 786 | |
| 787 | g_CurrentBuffer = (g_CurrentBuffer + 1) % SWAP_CHAIN_BUFFER_COUNT; |
| 788 | |
| 789 | UINT PresentInterval = s_EnableVSync ? std::min(4, (int)Round(s_FrameTime * 60.0f)) : 0; |
| 790 | |
| 791 | s_SwapChain1->Present(PresentInterval, 0); |
| 792 | |
| 793 | // Test robustness to handle spikes in CPU time |
| 794 | //if (s_DropRandomFrames) |
| 795 | //{ |
| 796 | // if (std::rand() % 25 == 0) |
| 797 | // BusyLoopSleep(0.010); |
| 798 | //} |
| 799 | |
| 800 | int64_t CurrentTick = SystemTime::GetCurrentTick(); |
| 801 | |
| 802 | if (s_EnableVSync) |
| 803 | { |
| 804 | // With VSync enabled, the time step between frames becomes a multiple of 16.666 ms. We need |
| 805 | // to add logic to vary between 1 and 2 (or 3 fields). This delta time also determines how |
| 806 | // long the previous frame should be displayed (i.e. the present interval.) |
| 807 | s_FrameTime = (s_LimitTo30Hz ? 2.0f : 1.0f) / 60.0f; |
| 808 | if (s_DropRandomFrames) |
| 809 | { |
| 810 | if (std::rand() % 50 == 0) |
| 811 | s_FrameTime += (1.0f / 60.0f); |
| 812 | } |
| 813 | } |
| 814 | else |
| 815 | { |
| 816 | // When running free, keep the most recent total frame time as the time step for |
| 817 | // the next frame simulation. This is not super-accurate, but assuming a frame |
| 818 | // time varies smoothly, it should be close enough. |
| 819 | s_FrameTime = (float)SystemTime::TimeBetweenTicks(s_FrameStartTick, CurrentTick); |
| 820 | } |
| 821 | |
| 822 | s_FrameStartTick = CurrentTick; |
| 823 | |
| 824 | ++s_FrameIndex; |
| 825 | TemporalEffects::Update((uint32_t)s_FrameIndex); |
| 826 | |
| 827 | SetNativeResolution(); |
| 828 | } |
| 829 | |
| 830 | uint64_t Graphics::GetFrameCount(void) |
| 831 | { |
nothing calls this directly
no test coverage detected