FrameRateLock
FrameRateLock
#Overview
name: FrameRateLock
The value of this variable can be defined or overridden in .ini config files. 1
.ini config file referencing this setting variable.
It is referenced in 5
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of FrameRateLock is to control the maximum frame rate of the game on iOS devices, primarily to manage power consumption and performance.
This setting variable is primarily relied upon by the iOS-specific subsystems of Unreal Engine, particularly the Metal RHI (Rendering Hardware Interface) and the iOS platform frame pacer. It’s also referenced in the Mac platform frame pacer, suggesting some shared functionality between iOS and macOS implementations.
The value of this variable is set in the IOSRuntimeSettings class, which is part of the IOSRuntimeSettings module. It’s defined as an UPROPERTY with the GlobalConfig and EditAnywhere attributes, meaning it can be modified in the project settings within the Unreal Engine editor.
FrameRateLock interacts with other variables such as bEnableDynamicMaxFPS and the device’s maximum refresh rate. It’s used to calculate the frame interval for the frame pacer and can affect the Metal present frame pacing.
Developers must be aware that:
- The FrameRateLock value is an enum (EPowerUsageFrameRateLock) and not a direct numeric value.
- It can be overridden via command line parameters.
- If set to 0, it defaults to the device’s maximum refresh rate.
- It’s used in conjunction with the maximum refresh rate of the device to calculate the actual frame interval.
Best practices when using this variable include:
- Consider the power consumption implications when setting this value. Lower frame rates can save battery life.
- Ensure the chosen frame rate lock is appropriate for the game’s performance requirements and target devices.
- Be aware that it can be overridden by command line parameters, which might be useful for debugging or testing.
- Consider using the bEnableDynamicMaxFPS option for more flexible frame rate management.
- Remember that changes to this setting may require restarting the application to take effect.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseEngine.ini:3003, section: [/Script/IOSRuntimeSettings.IOSRuntimeSettings]
- INI Section:
/Script/IOSRuntimeSettings.IOSRuntimeSettings
- Raw value:
PUFRL_30
- Is Array:
False
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/Apple/MetalRHI/Private/MetalContext.cpp:373
Scope (from outer to inner):
file
function FMetalDeviceContext::FMetalDeviceContext
Source code excerpt:
{
FString FrameRateLockAsEnum;
GConfig->GetString(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("FrameRateLock"), FrameRateLockAsEnum, GEngineIni);
uint32 FrameRateLock = 0;
FParse::Value(*FrameRateLockAsEnum, TEXT("PUFRL_"), FrameRateLock);
if (FrameRateLock > 0)
{
GMetalPresentFramePacing = (float)FrameRateLock;
}
}
}
const bool bIsVisionOS = PLATFORM_VISIONOS;
if (bIsVisionOS || FParse::Param(FCommandLine::Get(), TEXT("MetalIntermediateBackBuffer")) || FParse::Param(FCommandLine::Get(), TEXT("MetalOffscreenOnly")))
#Loc: <Workspace>/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSPlatformFramePacer.cpp:141
Scope (from outer to inner):
file
function bool FIOSPlatformRHIFramePacer::IsEnabled
Source code excerpt:
{
FString FrameRateLockAsEnum;
GConfig->GetString(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("FrameRateLock"), FrameRateLockAsEnum, GEngineIni);
uint32 MaxRefreshRate = GetMaxRefreshRate();
uint32 FrameRateLock = MaxRefreshRate;
FParse::Value(*FrameRateLockAsEnum, TEXT("PUFRL_"), FrameRateLock);
const bool bOverridesFrameRate = FParse::Value( FCommandLine::Get(), TEXT( "FrameRateLock=" ), FrameRateLockAsEnum );
if (bOverridesFrameRate)
{
FParse::Value(*FrameRateLockAsEnum, TEXT("PUFRL_"), FrameRateLock);
}
if (FrameRateLock == 0)
{
FrameRateLock = MaxRefreshRate;
}
if (!bIsRHIFramePacerEnabled)
{
check((MaxRefreshRate % FrameRateLock) == 0);
FrameInterval = MaxRefreshRate / FrameRateLock;
MinFrameInterval = FrameInterval;
bIsRHIFramePacerEnabled = (FrameInterval > 0);
// remember the Pace if we are enabled
Pace = bIsRHIFramePacerEnabled ? FrameRateLock : 0;
}
bInitialized = true;
}
return bIsRHIFramePacerEnabled;
#endif
#Loc: <Workspace>/Engine/Source/Runtime/ApplicationCore/Private/Mac/MacPlatformFramePacer.cpp:159
Scope (from outer to inner):
file
function void FMacFramePacer::Signal
Source code excerpt:
if (!bInitialized)
{
GConfig->GetBool(TEXT("/Script/MacTargetPlatform.MacTargetSettings"), TEXT("FrameRateLock"), bIsRHIFramePacerEnabled, GEngineIni);
bInitialized = true;
}
return bIsRHIFramePacerEnabled;
}
#Loc: <Workspace>/Engine/Source/Runtime/IOS/IOSRuntimeSettings/Classes/IOSRuntimeSettings.h:276
Scope (from outer to inner):
file
class class UIOSRuntimeSettings : public UObject
Source code excerpt:
/** Set the maximum frame rate to save on power consumption */
UPROPERTY(GlobalConfig, EditAnywhere, Category = PowerUsage, meta = (ConfigHierarchyEditable))
EPowerUsageFrameRateLock FrameRateLock;
//Whether or not to allow taking the MaxRefreshRate from the device instead of a constant (60fps) in IOSPlatformFramePacer
UPROPERTY(GlobalConfig, EditAnywhere, Category = PowerUsage, meta = (ConfigHierarchyEditable))
bool bEnableDynamicMaxFPS;
// Enable the use of RSync for remote builds on a mac
#Loc: <Workspace>/Engine/Source/Runtime/IOS/IOSRuntimeSettings/Private/IOSRuntimeSettings.cpp:35
Scope (from outer to inner):
file
function UIOSRuntimeSettings::UIOSRuntimeSettings
Source code excerpt:
BundleIdentifier = TEXT("com.YourCompany.GameNameNoSpaces");
VersionInfo = TEXT("1.0.0");
FrameRateLock = EPowerUsageFrameRateLock::PUFRL_30;
bEnableDynamicMaxFPS = false;
bSupportsIPad = true;
bSupportsIPhone = true;
bEnableSplitView = false;
bEnableSimulatorSupport = false;
MinimumiOSVersion = EIOSVersion::IOS_Minimum;