r.FinishCurrentFrame
r.FinishCurrentFrame
#Overview
name: r.FinishCurrentFrame
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
If on, the current frame will be forced to finish and render to the screen instead of being buffered. This will improve latency, but slow down overall performance.
It is referenced in 5
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of r.FinishCurrentFrame is to control frame rendering and presentation behavior in Unreal Engine’s rendering system. Specifically, it determines whether the current frame should be immediately rendered to the screen or buffered for later presentation.
This setting variable is primarily used by the rendering subsystem of Unreal Engine, particularly in the platform-specific RHI (Rendering Hardware Interface) implementations. Based on the callsites, it’s utilized in D3D11, D3D12, OpenGL, and potentially Vulkan rendering backends.
The value of this variable is set through the console variable system, as evidenced by its declaration as a TAutoConsoleVariable in the ConsoleManager.cpp file. It can be modified at runtime through console commands or configuration files.
The r.FinishCurrentFrame variable interacts closely with frame synchronization and presentation mechanisms. It affects how the engine handles frame events and GPU synchronization.
Developers must be aware that enabling this variable (setting it to 1) will improve latency but may negatively impact overall performance. This trade-off occurs because forcing immediate frame completion and rendering can reduce the engine’s ability to optimize rendering across multiple frames.
Best practices when using this variable include:
- Use it judiciously, primarily for debugging or in scenarios where minimizing latency is critical.
- Be aware of the performance implications when enabling it.
- Consider using it in conjunction with other rendering and performance-related settings to achieve the desired balance between latency and performance.
- Test thoroughly in various scenarios to ensure it doesn’t introduce unintended side effects in your specific use case.
- Remember that its effects may vary across different rendering backends (D3D11, D3D12, OpenGL, Vulkan), so test on all relevant platforms.
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/HAL/ConsoleManager.cpp:3850
Scope: file
Source code excerpt:
static TAutoConsoleVariable<int32> CVarFinishCurrentFrame(
TEXT("r.FinishCurrentFrame"),
0,
TEXT("If on, the current frame will be forced to finish and render to the screen instead of being buffered. This will improve latency, but slow down overall performance."),
ECVF_Scalability | ECVF_RenderThreadSafe);
static TAutoConsoleVariable<int32> CVarMaxAnistropy(
TEXT("r.MaxAnisotropy"),
#Loc: <Workspace>/Engine/Source/Runtime/D3D12RHI/Private/D3D12Viewport.cpp:932
Scope (from outer to inner):
file
function void FD3D12CommandContextBase::RHIEndDrawingViewport
Source code excerpt:
if (bNativelyPresented)
{
static const auto CFinishFrameVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.FinishCurrentFrame"));
if (!CFinishFrameVar->GetValueOnRenderThread())
{
// Wait for the GPU to finish rendering the previous frame before finishing this frame.
Viewport->WaitForFrameEventCompletion();
Viewport->IssueFrameEvent();
}
#Loc: <Workspace>/Engine/Source/Runtime/OpenGLDrv/Private/OpenGLViewport.cpp:190
Scope (from outer to inner):
file
function void FOpenGLDynamicRHI::RHIEndDrawingViewport
Source code excerpt:
if (bNeedFinishFrame)
{
static const auto CFinishFrameVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.FinishCurrentFrame"));
if (!CFinishFrameVar->GetValueOnRenderThread())
{
// Wait for the GPU to finish rendering the previous frame before finishing this frame.
Viewport->WaitForFrameEventCompletion();
Viewport->IssueFrameEvent();
}
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanRHI.cpp:1184
Scope (from outer to inner):
file
function void FVulkanCommandListContext::RHIEndDrawingViewport
Source code excerpt:
if (bNativePresent)
{
//#todo-rco: Check for r.FinishCurrentFrame
}
RHI->DrawingViewport = nullptr;
WriteBeginTimestamp(CommandBufferManager->GetActiveCmdBuffer());
}
#Loc: <Workspace>/Engine/Source/Runtime/Windows/D3D11RHI/Private/D3D11Viewport.cpp:790
Scope (from outer to inner):
file
function void FD3D11DynamicRHI::RHIEndDrawingViewport
Source code excerpt:
if (bNativelyPresented)
{
static const auto CFinishFrameVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.FinishCurrentFrame"));
if (!CFinishFrameVar->GetValueOnRenderThread())
{
// Wait for the GPU to finish rendering the previous frame before finishing this frame.
Viewport->WaitForFrameEventCompletion();
Viewport->IssueFrameEvent();
}