# FrameTiming

> Struct containing high level CPU and GPU frame timings and accompanying relevant data.

## Definition

* **Type:** Struct
* **Namespace:** [UnityEngine](/engine/6000.0/script-reference/unityengine.md)
* **Assembly:** UnityEngine.CoreModule

```csharp
public struct FrameTiming
```

## Remarks

Use the FrameTiming struct to get access to the duration of CPU and GPU activities, their start time and other important performance information.

Use the following FrameTiming properties to determine CPU and GPU contributions to the frame time:

* [FrameTiming.cpuFrameTime](/engine/6000.0/script-reference/unityengine/frametiming/cpuframetime.md) refers to the total CPU frame time. It is calculated as the time between the start of the frame and the next frame on the main thread.
* [FrameTiming.cpuMainThreadFrameTime](/engine/6000.0/script-reference/unityengine/frametiming/cpumainthreadframetime.md) is the main thread’s work time, or the total amount of time between the start of the frame and the main thread finishing its work.
* [FrameTiming.cpuRenderThreadFrameTime](/engine/6000.0/script-reference/unityengine/frametiming/cpurenderthreadframetime.md) refers to the render thread’s work time, or the total amount of time between the first work request submitted to the render thread and the time when the `Present` method is called.
* [FrameTiming.cpuMainThreadPresentWaitTime](/engine/6000.0/script-reference/unityengine/frametiming/cpumainthreadpresentwaittime.md) is the duration the CPU spends waiting for `Present` to complete during the frame.
* [FrameTiming.gpuFrameTime](/engine/6000.0/script-reference/unityengine/frametiming/gpuframetime.md) is the GPU’s work time, or the total amount of time between the work submitted to the GPU and the signal indicating that the GPU has finished the job for the frame. The total time includes durations of all active and idle GPU states within frame.

The [FrameTiming.cpuMainThreadPresentWaitTime](/engine/6000.0/script-reference/unityengine/frametiming/cpumainthreadpresentwaittime.md) is the sum of displayed `[wait]` blocks, and includes waits for `Present` and target fps. It’s harder to calculate GPU work time, because it starts somewhere in the middle of scene rendering processes and finishes on the next frame's sync point with the previous frame.

The example demonstrates how to determine whether a frame is CPU or GPU bound.

```csharp
using Unity.Profiling;
using UnityEngine;

public class ExampleScript : MonoBehaviour
{
    internal enum PerformanceBottleneck
    {
        Indeterminate, // Cannot be determined
        PresentLimited, // Limited by presentation (vsync or framerate cap)
        CPU, // Limited by CPU (main and/or render thread)
        GPU, // Limited by GPU
        Balanced, // Limited by both CPU and GPU, i.e. well balanced
    }

    FrameTiming[] m_FrameTimings = new FrameTiming[1];

    void Update()
    {
        FrameTimingManager.CaptureFrameTimings();
        var ret = FrameTimingManager.GetLatestTimings((uint)m_FrameTimings.Length, m_FrameTimings);
        if (ret > 0)
        {
            var bottleneck = DetermineBottleneck(m_FrameTimings[0]);
            // Your code logic here
        }
    }

    static PerformanceBottleneck DetermineBottleneck(FrameTiming s)
    {
        const float kNearFullFrameTimeThresholdPercent = 0.2f;
        const float kNonZeroPresentWaitTimeMs = 0.5f;

        // If we're on platform which doesn't support GPU time
        if (s.gpuFrameTime == 0)
            return PerformanceBottleneck.Indeterminate;

        var fullFrameTimeWithMargin = (1f - kNearFullFrameTimeThresholdPercent) * s.cpuFrameTime;

        // GPU time is close to frame time, CPU times are not
        if (s.gpuFrameTime > fullFrameTimeWithMargin &&
            s.cpuMainThreadFrameTime < fullFrameTimeWithMargin &&
            s.cpuRenderThreadFrameTime < fullFrameTimeWithMargin)
            return PerformanceBottleneck.GPU;

        // One of the CPU times is close to frame time, GPU is not
        if (s.gpuFrameTime < fullFrameTimeWithMargin &&
            (s.cpuMainThreadFrameTime > fullFrameTimeWithMargin ||
            s.cpuRenderThreadFrameTime > fullFrameTimeWithMargin))
            return PerformanceBottleneck.CPU;

        // Main thread waited due to Vsync or target frame rate
        if (s.cpuMainThreadPresentWaitTime > kNonZeroPresentWaitTimeMs)
        {
            // None of the times are close to frame time
            if (s.gpuFrameTime < fullFrameTimeWithMargin &&
               s.cpuMainThreadFrameTime < fullFrameTimeWithMargin &&
               s.cpuRenderThreadFrameTime < fullFrameTimeWithMargin)
               return PerformanceBottleneck.PresentLimited;
         }

        return PerformanceBottleneck.Balanced;
    }
}
```

The FrameTiming also contains timestamp information that can be used for frame timeline visualization or calculating deltas with other markers. The timestamps provided are:

* [FrameTiming.frameStartTimestamp](/engine/6000.0/script-reference/unityengine/frametiming/framestarttimestamp.md): The CPU clock time when the frame first starts.
* [FrameTiming.firstSubmitTimestamp](/engine/6000.0/script-reference/unityengine/frametiming/firstsubmittimestamp.md): The CPU clock time when the initial work is submitted to the GPU during the frame (platform and API dependent). Different platforms submit at different times.
* [FrameTiming.cpuTimePresentCalled](/engine/6000.0/script-reference/unityengine/frametiming/cputimepresentcalled.md): The CPU clock time at the point Present() is called for the frame. It’s the time when Unity finishes submitting objects for rendering and informs the GPU that the frame can be presented to the user.
* [FrameTiming.cpuTimeFrameComplete](/engine/6000.0/script-reference/unityengine/frametiming/cputimeframecomplete.md): The CPU clock time at the point when the GPU finishes rendering the frame. On most platforms, this value is calculated and equals First Submit Timestamp + Frame GPU time.

Use [FrameTimingManager.GetCpuTimerFrequency](/engine/6000.0/script-reference/unityengine/frametimingmanager/getcputimerfrequency.md) to convert timestamps to seconds.

Additional Resources: [Introduction to the Frame Timing Manager](/engine/6000.0/manual/analysis/graphics-performance-profiling/profile-rendering/frame-timing-manager/manager.md), [FrameTimingManager](/engine/6000.0/script-reference/unityengine/frametimingmanager.md).

## Fields

| Value                                                                                                                   | Description                                                                                                                               |
| ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| [cpuFrameTime](/engine/6000.0/script-reference/unityengine/frametiming/cpuframetime.md)                                 | This is the total CPU frame time calculated as the time between ends of two frames, which includes all waiting time and overheads, in ms. |
| [cpuMainThreadFrameTime](/engine/6000.0/script-reference/unityengine/frametiming/cpumainthreadframetime.md)             | Total time between start of the frame and when the main thread finished the job, in ms.                                                   |
| [cpuMainThreadPresentWaitTime](/engine/6000.0/script-reference/unityengine/frametiming/cpumainthreadpresentwaittime.md) | The CPU time the last frame spent in waiting for Present on the main thread, in ms.                                                       |
| [cpuRenderThreadFrameTime](/engine/6000.0/script-reference/unityengine/frametiming/cpurenderthreadframetime.md)         | The frame time between start of the work on the render thread and when Present was called, in ms.                                         |
| [cpuTimeFrameComplete](/engine/6000.0/script-reference/unityengine/frametiming/cputimeframecomplete.md)                 | This is the CPU clock time at the point GPU finished rendering the frame and interrupted the CPU.                                         |
| [cpuTimePresentCalled](/engine/6000.0/script-reference/unityengine/frametiming/cputimepresentcalled.md)                 | This is the CPU clock time at the point Present was called for the current frame.                                                         |
| [firstSubmitTimestamp](/engine/6000.0/script-reference/unityengine/frametiming/firstsubmittimestamp.md)                 | This is the CPU clock time of the time when the first job was submitted to GPU.                                                           |
| [frameStartTimestamp](/engine/6000.0/script-reference/unityengine/frametiming/framestarttimestamp.md)                   | This is the CPU clock time of the time when the frame was started.                                                                        |
| [gpuFrameTime](/engine/6000.0/script-reference/unityengine/frametiming/gpuframetime.md)                                 | The GPU time for a given frame, in ms.                                                                                                    |
| [heightScale](/engine/6000.0/script-reference/unityengine/frametiming/heightscale.md)                                   | This was the height scale factor of the Dynamic Resolution system(if used) for the given frame and the linked frame timings.              |
| [syncInterval](/engine/6000.0/script-reference/unityengine/frametiming/syncinterval.md)                                 | This was the vsync mode for the given frame and the linked frame timings.                                                                 |
| [widthScale](/engine/6000.0/script-reference/unityengine/frametiming/widthscale.md)                                     | This was the width scale factor of the Dynamic Resolution system(if used) for the given frame and the linked frame timings.               |
