Monado OpenXR Runtime
u_pacing_compositor.c File Reference

Shared frame timing code. More...

#include "os/os_time.h"
#include "util/u_time.h"
#include "util/u_misc.h"
#include "util/u_debug.h"
#include "util/u_pacing.h"
#include "util/u_metrics.h"
#include "util/u_logging.h"
#include "util/u_trace_marker.h"
#include <stdio.h>
#include <assert.h>
#include <inttypes.h>
Include dependency graph for u_pacing_compositor.c:

Data Structures

struct  frame
 
struct  pacing_compositor
 

Macros

#define UPC_LOG_T(...)   U_LOG_IFL_T(debug_get_log_option_log_level(), __VA_ARGS__)
 
#define UPC_LOG_D(...)   U_LOG_IFL_D(debug_get_log_option_log_level(), __VA_ARGS__)
 
#define UPC_LOG_I(...)   U_LOG_IFL_I(debug_get_log_option_log_level(), __VA_ARGS__)
 
#define UPC_LOG_W(...)   U_LOG_IFL_W(debug_get_log_option_log_level(), __VA_ARGS__)
 
#define UPC_LOG_E(...)   U_LOG_IFL_E(debug_get_log_option_log_level(), __VA_ARGS__)
 
#define NUM_FRAMES   16
 
#define PRESENT_SLOP_NS   (U_TIME_HALF_MS_IN_NS)
 

Enumerations

enum  frame_state {
  STATE_SKIPPED = -1 , STATE_CLEARED = 0 , STATE_PREDICTED = 1 , STATE_WOKE = 2 ,
  STATE_BEGAN = 3 , STATE_SUBMITTED = 4 , STATE_INFO = 5
}
 

Functions

static struct pacing_compositorpacing_compositor (struct u_pacing_compositor *upc)
 
static double ns_to_ms (int64_t t)
 
static uint64_t get_percent_of_time (uint64_t time_ns, uint32_t fraction_percent)
 
static uint64_t calc_total_comp_time (struct pacing_compositor *pc)
 
static uint64_t calc_display_time_from_present_time (struct pacing_compositor *pc, uint64_t desired_present_time_ns)
 
static bool is_within_of_each_other (uint64_t l, uint64_t r, uint64_t range)
 
static bool is_within_half_ms (uint64_t l, uint64_t r)
 
static struct frameget_frame (struct pacing_compositor *pc, int64_t frame_id)
 Gets a frame data structure based on the frame_id. More...
 
static struct framecreate_frame (struct pacing_compositor *pc, enum frame_state state)
 Assign the next available frame ID, initialize the corresponding frame data with the ID and state, and return a pointer to that frame data. More...
 
static struct frameget_latest_frame_with_state_at_least (struct pacing_compositor *pc, enum frame_state state)
 Gets the most recent frame data whose state is greater than or equal to state, if any. More...
 
static struct framedo_clean_slate_frame (struct pacing_compositor *pc, uint64_t now_ns)
 "Create" a frame ID in state frame_state::STATE_PREDICTED (by calling create_frame), and additionally initialize frame::desired_present_time_ns (with a crude estimate) and frame::when_predict_ns. More...
 
static struct framewalk_forward_through_frames (struct pacing_compositor *pc, uint64_t last_present_time_ns, uint64_t now_ns)
 Find the next possible present time for rendering that has not yet occurred, and create a frame/frame id with that prediction in it. More...
 
static struct framepredict_next_frame (struct pacing_compositor *pc, uint64_t now_ns)
 
static void adjust_comp_time (struct pacing_compositor *pc, struct frame *f)
 
static void do_metrics (struct pacing_compositor *pc, struct frame *f)
 
static void do_tracing (struct pacing_compositor *pc, struct frame *f)
 
static void pc_predict (struct u_pacing_compositor *upc, uint64_t now_ns, int64_t *out_frame_id, uint64_t *out_wake_up_time_ns, uint64_t *out_desired_present_time_ns, uint64_t *out_present_slop_ns, uint64_t *out_predicted_display_time_ns, uint64_t *out_predicted_display_period_ns, uint64_t *out_min_display_period_ns)
 
static void pc_mark_point (struct u_pacing_compositor *upc, enum u_timing_point point, int64_t frame_id, uint64_t when_ns)
 
static void pc_info (struct u_pacing_compositor *upc, int64_t frame_id, uint64_t desired_present_time_ns, uint64_t actual_present_time_ns, uint64_t earliest_present_time_ns, uint64_t present_margin_ns, uint64_t when_ns)
 
static void pc_info_gpu (struct u_pacing_compositor *upc, int64_t frame_id, uint64_t gpu_start_ns, uint64_t gpu_end_ns, uint64_t when_ns)
 
static void pc_update_vblank_from_display_control (struct u_pacing_compositor *upc, uint64_t last_vblank_ns)
 
static void pc_update_present_offset (struct u_pacing_compositor *upc, int64_t frame_id, uint64_t present_to_display_offset_ns)
 
static void pc_destroy (struct u_pacing_compositor *upc)
 
xrt_result_t u_pc_display_timing_create (uint64_t estimated_frame_period_ns, const struct u_pc_display_timing_config *config, struct u_pacing_compositor **out_upc)
 Creates a new composition pacing helper that uses real display timing information. More...
 

Variables

const struct u_pc_display_timing_config U_PC_DISPLAY_TIMING_CONFIG_DEFAULT
 Default configuration values for display-timing-aware compositor pacing. More...
 

Detailed Description

Shared frame timing code.

Author
Jakob Bornecrantz jakob.nosp@m.@col.nosp@m.labor.nosp@m.a.co.nosp@m.m

Function Documentation

◆ create_frame()

static struct frame * create_frame ( struct pacing_compositor pc,
enum frame_state  state 
)
static

Assign the next available frame ID, initialize the corresponding frame data with the ID and state, and return a pointer to that frame data.

Fields other than frame::frame_id and frame::state are not modified, so may have old data in them. This may be a feature rather than a bug.

References frame::frame_id, get_frame(), and pacing_compositor::next_frame_id.

Referenced by do_clean_slate_frame().

◆ do_clean_slate_frame()

static struct frame * do_clean_slate_frame ( struct pacing_compositor pc,
uint64_t  now_ns 
)
static

"Create" a frame ID in state frame_state::STATE_PREDICTED (by calling create_frame), and additionally initialize frame::desired_present_time_ns (with a crude estimate) and frame::when_predict_ns.

References create_frame().

◆ get_frame()

static struct frame * get_frame ( struct pacing_compositor pc,
int64_t  frame_id 
)
static

Gets a frame data structure based on the frame_id.

Note that this is done modulo the number of frame data structs we hold: the data in the frame you receive may not match the frame_id you passed!

See also
create_frame to create a frame id and (partially) initialize the frame data structure, do_clean_slate_frame for a more complete initialization

References frame::frame_id.

Referenced by create_frame().

◆ get_latest_frame_with_state_at_least()

static struct frame * get_latest_frame_with_state_at_least ( struct pacing_compositor pc,
enum frame_state  state 
)
static

Gets the most recent frame data whose state is greater than or equal to state, if any.

Returns
a frame pointer, or null if no frames have at least state

References pacing_compositor::next_frame_id.

◆ walk_forward_through_frames()

static struct frame * walk_forward_through_frames ( struct pacing_compositor pc,
uint64_t  last_present_time_ns,
uint64_t  now_ns 
)
static

Find the next possible present time for rendering that has not yet occurred, and create a frame/frame id with that prediction in it.

Variable Documentation

◆ U_PC_DISPLAY_TIMING_CONFIG_DEFAULT

const struct u_pc_display_timing_config U_PC_DISPLAY_TIMING_CONFIG_DEFAULT
Initial value:
= {
.present_to_display_offset_ns = U_TIME_1MS_IN_NS * 4,
.margin_ns = U_TIME_1MS_IN_NS,
.comp_time_fraction = 10,
.comp_time_max_fraction = 30,
.adjust_missed_fraction = 4,
.adjust_non_miss_fraction = 2,
}
#define U_TIME_1MS_IN_NS
The number of nanoseconds in a millisecond.
Definition: u_time.h:54

Default configuration values for display-timing-aware compositor pacing.

See also
u_pc_display_timing_config, u_pc_display_timing_create