mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-29 18:08:29 +00:00
aux/util: use int64_t for timestamps in u_pacing
Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2298>
This commit is contained in:
parent
8cf2e4bd2b
commit
f88705a307
|
@ -83,14 +83,14 @@ struct u_pacing_compositor
|
|||
* @see @ref frame-pacing.
|
||||
*/
|
||||
void (*predict)(struct u_pacing_compositor *upc,
|
||||
uint64_t now_ns,
|
||||
int64_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);
|
||||
int64_t *out_wake_up_time_ns,
|
||||
int64_t *out_desired_present_time_ns,
|
||||
int64_t *out_present_slop_ns,
|
||||
int64_t *out_predicted_display_time_ns,
|
||||
int64_t *out_predicted_display_period_ns,
|
||||
int64_t *out_min_display_period_ns);
|
||||
|
||||
/*!
|
||||
* Mark a point on the frame's lifetime.
|
||||
|
@ -108,7 +108,7 @@ struct u_pacing_compositor
|
|||
void (*mark_point)(struct u_pacing_compositor *upc,
|
||||
enum u_timing_point point,
|
||||
int64_t frame_id,
|
||||
uint64_t when_ns);
|
||||
int64_t when_ns);
|
||||
|
||||
/*!
|
||||
* Provide frame timing information about a delivered frame.
|
||||
|
@ -136,11 +136,11 @@ struct u_pacing_compositor
|
|||
*/
|
||||
void (*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);
|
||||
int64_t desired_present_time_ns,
|
||||
int64_t actual_present_time_ns,
|
||||
int64_t earliest_present_time_ns,
|
||||
int64_t present_margin_ns,
|
||||
int64_t when_ns);
|
||||
|
||||
/*!
|
||||
* Provide frame timing information about GPU start and stop time.
|
||||
|
@ -159,9 +159,9 @@ struct u_pacing_compositor
|
|||
*/
|
||||
void (*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);
|
||||
int64_t gpu_start_ns,
|
||||
int64_t gpu_end_ns,
|
||||
int64_t when_ns);
|
||||
|
||||
/*!
|
||||
* Provide a vblank timing information, derived from the
|
||||
|
@ -174,7 +174,7 @@ struct u_pacing_compositor
|
|||
*
|
||||
* @see @ref frame-pacing.
|
||||
*/
|
||||
void (*update_vblank_from_display_control)(struct u_pacing_compositor *upc, uint64_t last_vblank_ns);
|
||||
void (*update_vblank_from_display_control)(struct u_pacing_compositor *upc, int64_t last_vblank_ns);
|
||||
|
||||
/*!
|
||||
* Provide an updated estimate of the present offset.
|
||||
|
@ -189,7 +189,7 @@ struct u_pacing_compositor
|
|||
*/
|
||||
void (*update_present_offset)(struct u_pacing_compositor *upc,
|
||||
int64_t frame_id,
|
||||
uint64_t present_to_display_offset_ns);
|
||||
int64_t present_to_display_offset_ns);
|
||||
|
||||
/*!
|
||||
* Destroy this u_pacing_compositor.
|
||||
|
@ -207,14 +207,14 @@ struct u_pacing_compositor
|
|||
*/
|
||||
static inline void
|
||||
u_pc_predict(struct u_pacing_compositor *upc,
|
||||
uint64_t now_ns,
|
||||
int64_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)
|
||||
int64_t *out_wake_up_time_ns,
|
||||
int64_t *out_desired_present_time_ns,
|
||||
int64_t *out_present_slop_ns,
|
||||
int64_t *out_predicted_display_time_ns,
|
||||
int64_t *out_predicted_display_period_ns,
|
||||
int64_t *out_min_display_period_ns)
|
||||
{
|
||||
upc->predict(upc, //
|
||||
now_ns, //
|
||||
|
@ -236,7 +236,7 @@ u_pc_predict(struct u_pacing_compositor *upc,
|
|||
* @ingroup aux_pacing
|
||||
*/
|
||||
static inline void
|
||||
u_pc_mark_point(struct u_pacing_compositor *upc, enum u_timing_point point, int64_t frame_id, uint64_t when_ns)
|
||||
u_pc_mark_point(struct u_pacing_compositor *upc, enum u_timing_point point, int64_t frame_id, int64_t when_ns)
|
||||
{
|
||||
upc->mark_point(upc, point, frame_id, when_ns);
|
||||
}
|
||||
|
@ -252,11 +252,11 @@ u_pc_mark_point(struct u_pacing_compositor *upc, enum u_timing_point point, int6
|
|||
static inline void
|
||||
u_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)
|
||||
int64_t desired_present_time_ns,
|
||||
int64_t actual_present_time_ns,
|
||||
int64_t earliest_present_time_ns,
|
||||
int64_t present_margin_ns,
|
||||
int64_t when_ns)
|
||||
{
|
||||
upc->info(upc, frame_id, desired_present_time_ns, actual_present_time_ns, earliest_present_time_ns,
|
||||
present_margin_ns, when_ns);
|
||||
|
@ -273,7 +273,7 @@ u_pc_info(struct u_pacing_compositor *upc,
|
|||
*/
|
||||
static inline void
|
||||
u_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)
|
||||
struct u_pacing_compositor *upc, int64_t frame_id, int64_t gpu_start_ns, int64_t gpu_end_ns, int64_t when_ns)
|
||||
{
|
||||
upc->info_gpu(upc, frame_id, gpu_start_ns, gpu_end_ns, when_ns);
|
||||
}
|
||||
|
@ -287,7 +287,7 @@ u_pc_info_gpu(
|
|||
* @ingroup aux_pacing
|
||||
*/
|
||||
static inline void
|
||||
u_pc_update_vblank_from_display_control(struct u_pacing_compositor *upc, uint64_t last_vblank_ns)
|
||||
u_pc_update_vblank_from_display_control(struct u_pacing_compositor *upc, int64_t last_vblank_ns)
|
||||
{
|
||||
upc->update_vblank_from_display_control(upc, last_vblank_ns);
|
||||
}
|
||||
|
@ -301,7 +301,7 @@ u_pc_update_vblank_from_display_control(struct u_pacing_compositor *upc, uint64_
|
|||
* @ingroup aux_pacing
|
||||
*/
|
||||
static inline void
|
||||
u_pc_update_present_offset(struct u_pacing_compositor *upc, int64_t frame_id, uint64_t present_to_display_offset_ns)
|
||||
u_pc_update_present_offset(struct u_pacing_compositor *upc, int64_t frame_id, int64_t present_to_display_offset_ns)
|
||||
{
|
||||
upc->update_present_offset(upc, frame_id, present_to_display_offset_ns);
|
||||
}
|
||||
|
@ -362,11 +362,11 @@ struct u_pacing_app
|
|||
* @param[out] out_predicted_display_period Predicted display period.
|
||||
*/
|
||||
void (*predict)(struct u_pacing_app *upa,
|
||||
uint64_t now_ns,
|
||||
int64_t now_ns,
|
||||
int64_t *out_frame_id,
|
||||
uint64_t *out_wake_up_time,
|
||||
uint64_t *out_predicted_display_time,
|
||||
uint64_t *out_predicted_display_period);
|
||||
int64_t *out_wake_up_time,
|
||||
int64_t *out_predicted_display_time,
|
||||
int64_t *out_predicted_display_period);
|
||||
|
||||
/*!
|
||||
* Mark a point on the frame's lifetime.
|
||||
|
@ -378,7 +378,7 @@ struct u_pacing_app
|
|||
*
|
||||
* @see @ref frame-pacing.
|
||||
*/
|
||||
void (*mark_point)(struct u_pacing_app *upa, int64_t frame_id, enum u_timing_point point, uint64_t when_ns);
|
||||
void (*mark_point)(struct u_pacing_app *upa, int64_t frame_id, enum u_timing_point point, int64_t when_ns);
|
||||
|
||||
/*!
|
||||
* When a frame has been discarded.
|
||||
|
@ -387,7 +387,7 @@ struct u_pacing_app
|
|||
* @param[in] frame_id The frame ID to mark as discarded.
|
||||
* @param[in] when_ns The time when it was discarded, nominally from @ref os_monotonic_get_ns
|
||||
*/
|
||||
void (*mark_discarded)(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns);
|
||||
void (*mark_discarded)(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns);
|
||||
|
||||
/*!
|
||||
* A frame has been delivered from the client, see `xrEndFrame`. The GPU might
|
||||
|
@ -398,7 +398,7 @@ struct u_pacing_app
|
|||
* @param[in] when_ns The time when it was delivered, nominally from @ref os_monotonic_get_ns
|
||||
* @param[in] display_time_ns The time the frame is to be displayed.
|
||||
*/
|
||||
void (*mark_delivered)(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns, uint64_t display_time_ns);
|
||||
void (*mark_delivered)(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns, int64_t display_time_ns);
|
||||
|
||||
/*!
|
||||
* A frame has been completed rendered by the GPU, this can happen after `xrEndFrame` has returned.
|
||||
|
@ -407,7 +407,7 @@ struct u_pacing_app
|
|||
* @param[in] frame_id The frame ID to mark as delivered.
|
||||
* @param[in] when_ns The time when it the gpu was finished, nominally from @ref os_monotonic_get_ns
|
||||
*/
|
||||
void (*mark_gpu_done)(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns);
|
||||
void (*mark_gpu_done)(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns);
|
||||
|
||||
/*!
|
||||
* Latch a frame for rendering for delivery to the native compositor,
|
||||
|
@ -420,7 +420,7 @@ struct u_pacing_app
|
|||
* @param[in] system_frame_id The ID of the system frame that is
|
||||
* latching the app's frame.
|
||||
*/
|
||||
void (*latched)(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns, int64_t system_frame_id);
|
||||
void (*latched)(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns, int64_t system_frame_id);
|
||||
|
||||
/*!
|
||||
* Mark a frame as completely retired, will never be latched (used by
|
||||
|
@ -431,7 +431,7 @@ struct u_pacing_app
|
|||
* @param[in] frame_id The frame ID of the latched frame.
|
||||
* @param[in] when_ns Time when the latching happened.
|
||||
*/
|
||||
void (*retired)(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns);
|
||||
void (*retired)(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns);
|
||||
|
||||
/*!
|
||||
* Add a new sample point from the main render loop.
|
||||
|
@ -452,9 +452,9 @@ struct u_pacing_app
|
|||
* was woken up by the main compositor.
|
||||
*/
|
||||
void (*info)(struct u_pacing_app *upa,
|
||||
uint64_t predicted_display_time_ns,
|
||||
uint64_t predicted_display_period_ns,
|
||||
uint64_t extra_ns);
|
||||
int64_t predicted_display_time_ns,
|
||||
int64_t predicted_display_period_ns,
|
||||
int64_t extra_ns);
|
||||
|
||||
/*!
|
||||
* Destroy this u_pacing_app.
|
||||
|
@ -472,11 +472,11 @@ struct u_pacing_app
|
|||
*/
|
||||
static inline void
|
||||
u_pa_predict(struct u_pacing_app *upa,
|
||||
uint64_t now_ns,
|
||||
int64_t now_ns,
|
||||
int64_t *out_frame_id,
|
||||
uint64_t *out_wake_up_time,
|
||||
uint64_t *out_predicted_display_time,
|
||||
uint64_t *out_predicted_display_period)
|
||||
int64_t *out_wake_up_time,
|
||||
int64_t *out_predicted_display_time,
|
||||
int64_t *out_predicted_display_period)
|
||||
{
|
||||
upa->predict(upa, now_ns, out_frame_id, out_wake_up_time, out_predicted_display_time,
|
||||
out_predicted_display_period);
|
||||
|
@ -491,7 +491,7 @@ u_pa_predict(struct u_pacing_app *upa,
|
|||
* @ingroup aux_pacing
|
||||
*/
|
||||
static inline void
|
||||
u_pa_mark_point(struct u_pacing_app *upa, int64_t frame_id, enum u_timing_point point, uint64_t when_ns)
|
||||
u_pa_mark_point(struct u_pacing_app *upa, int64_t frame_id, enum u_timing_point point, int64_t when_ns)
|
||||
{
|
||||
upa->mark_point(upa, frame_id, point, when_ns);
|
||||
}
|
||||
|
@ -505,7 +505,7 @@ u_pa_mark_point(struct u_pacing_app *upa, int64_t frame_id, enum u_timing_point
|
|||
* @ingroup aux_pacing
|
||||
*/
|
||||
static inline void
|
||||
u_pa_mark_discarded(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns)
|
||||
u_pa_mark_discarded(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns)
|
||||
{
|
||||
upa->mark_discarded(upa, frame_id, when_ns);
|
||||
}
|
||||
|
@ -519,7 +519,7 @@ u_pa_mark_discarded(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns
|
|||
* @ingroup aux_pacing
|
||||
*/
|
||||
static inline void
|
||||
u_pa_mark_delivered(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns, uint64_t display_time_ns)
|
||||
u_pa_mark_delivered(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns, int64_t display_time_ns)
|
||||
{
|
||||
upa->mark_delivered(upa, frame_id, when_ns, display_time_ns);
|
||||
}
|
||||
|
@ -533,7 +533,7 @@ u_pa_mark_delivered(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns
|
|||
* @ingroup aux_pacing
|
||||
*/
|
||||
static inline void
|
||||
u_pa_mark_gpu_done(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns)
|
||||
u_pa_mark_gpu_done(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns)
|
||||
{
|
||||
upa->mark_gpu_done(upa, frame_id, when_ns);
|
||||
}
|
||||
|
@ -548,9 +548,9 @@ u_pa_mark_gpu_done(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns)
|
|||
*/
|
||||
static inline void
|
||||
u_pa_info(struct u_pacing_app *upa,
|
||||
uint64_t predicted_display_time_ns,
|
||||
uint64_t predicted_display_period_ns,
|
||||
uint64_t extra_ns)
|
||||
int64_t predicted_display_time_ns,
|
||||
int64_t predicted_display_period_ns,
|
||||
int64_t extra_ns)
|
||||
{
|
||||
upa->info(upa, predicted_display_time_ns, predicted_display_period_ns, extra_ns);
|
||||
}
|
||||
|
@ -564,7 +564,7 @@ u_pa_info(struct u_pacing_app *upa,
|
|||
* @ingroup aux_pacing
|
||||
*/
|
||||
static inline void
|
||||
u_pa_latched(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns, int64_t system_frame_id)
|
||||
u_pa_latched(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns, int64_t system_frame_id)
|
||||
{
|
||||
upa->latched(upa, frame_id, when_ns, system_frame_id);
|
||||
}
|
||||
|
@ -578,7 +578,7 @@ u_pa_latched(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns, int64
|
|||
* @ingroup aux_pacing
|
||||
*/
|
||||
static inline void
|
||||
u_pa_retired(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns)
|
||||
u_pa_retired(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns)
|
||||
{
|
||||
upa->retired(upa, frame_id, when_ns);
|
||||
}
|
||||
|
@ -680,9 +680,9 @@ u_paf_destroy(struct u_pacing_app_factory **upaf_ptr)
|
|||
struct u_pc_display_timing_config
|
||||
{
|
||||
//! How long after "present" is the image actually displayed
|
||||
uint64_t present_to_display_offset_ns;
|
||||
int64_t present_to_display_offset_ns;
|
||||
//! Extra margin that is added to compositor time, between end of draw and present
|
||||
uint64_t margin_ns;
|
||||
int64_t margin_ns;
|
||||
/*!
|
||||
* @name Frame-Relative Values
|
||||
* All these values are in "percentage points of the nominal frame period" so they can work across
|
||||
|
@ -725,7 +725,7 @@ extern const struct u_pc_display_timing_config U_PC_DISPLAY_TIMING_CONFIG_DEFAUL
|
|||
* @see u_pacing_compositor
|
||||
*/
|
||||
xrt_result_t
|
||||
u_pc_display_timing_create(uint64_t estimated_frame_period_ns,
|
||||
u_pc_display_timing_create(int64_t estimated_frame_period_ns,
|
||||
const struct u_pc_display_timing_config *config,
|
||||
struct u_pacing_compositor **out_upc);
|
||||
|
||||
|
@ -742,7 +742,7 @@ u_pc_display_timing_create(uint64_t estimated_frame_period_ns,
|
|||
* @see u_pacing_compositor
|
||||
*/
|
||||
xrt_result_t
|
||||
u_pc_fake_create(uint64_t estimated_frame_period_ns, uint64_t now_ns, struct u_pacing_compositor **out_upc);
|
||||
u_pc_fake_create(int64_t estimated_frame_period_ns, int64_t now_ns, struct u_pacing_compositor **out_upc);
|
||||
|
||||
/*!
|
||||
* Creates a new application pacing factory helper.
|
||||
|
|
|
@ -68,34 +68,34 @@ struct u_pa_frame
|
|||
int64_t frame_id;
|
||||
|
||||
//! How long we thought the frame would take.
|
||||
uint64_t predicted_frame_time_ns;
|
||||
int64_t predicted_frame_time_ns;
|
||||
|
||||
//! When we predicted the app should wake up.
|
||||
uint64_t predicted_wake_up_time_ns;
|
||||
int64_t predicted_wake_up_time_ns;
|
||||
|
||||
//! When the client's GPU work should have completed.
|
||||
uint64_t predicted_gpu_done_time_ns;
|
||||
int64_t predicted_gpu_done_time_ns;
|
||||
|
||||
//! When we predicted this frame to be shown.
|
||||
uint64_t predicted_display_time_ns;
|
||||
int64_t predicted_display_time_ns;
|
||||
|
||||
//! The selected display period.
|
||||
uint64_t predicted_display_period_ns;
|
||||
int64_t predicted_display_period_ns;
|
||||
|
||||
/*!
|
||||
* When the app told us to display this frame, can be different
|
||||
* then the predicted display time so we track that separately.
|
||||
*/
|
||||
uint64_t display_time_ns;
|
||||
int64_t display_time_ns;
|
||||
|
||||
//! When something happened.
|
||||
struct
|
||||
{
|
||||
uint64_t predicted_ns;
|
||||
uint64_t wait_woke_ns;
|
||||
uint64_t begin_ns;
|
||||
uint64_t delivered_ns;
|
||||
uint64_t gpu_done_ns;
|
||||
int64_t predicted_ns;
|
||||
int64_t wait_woke_ns;
|
||||
int64_t begin_ns;
|
||||
int64_t delivered_ns;
|
||||
int64_t gpu_done_ns;
|
||||
} when;
|
||||
|
||||
enum u_pa_state state;
|
||||
|
@ -140,24 +140,24 @@ struct pacing_app
|
|||
struct
|
||||
{
|
||||
//! App time between wait returning and begin being called.
|
||||
uint64_t cpu_time_ns;
|
||||
int64_t cpu_time_ns;
|
||||
//! Time between begin and frame data being delivered.
|
||||
uint64_t draw_time_ns;
|
||||
int64_t draw_time_ns;
|
||||
//! Time between the frame data being delivered and GPU completing.
|
||||
uint64_t gpu_time_ns;
|
||||
int64_t gpu_time_ns;
|
||||
} app; //!< App statistics.
|
||||
|
||||
struct
|
||||
{
|
||||
//! The last display time that the thing driving this helper got.
|
||||
uint64_t predicted_display_time_ns;
|
||||
int64_t predicted_display_time_ns;
|
||||
//! The last display period the hardware is running at.
|
||||
uint64_t predicted_display_period_ns;
|
||||
int64_t predicted_display_period_ns;
|
||||
//! The extra time needed by the thing driving this helper.
|
||||
uint64_t extra_ns;
|
||||
int64_t extra_ns;
|
||||
} last_input;
|
||||
|
||||
uint64_t last_returned_ns;
|
||||
int64_t last_returned_ns;
|
||||
};
|
||||
|
||||
|
||||
|
@ -204,56 +204,56 @@ point_to_str(enum u_timing_point point)
|
|||
#define DEBUG_PRINT_ID_FRAME_POINT(ID, F, P) \
|
||||
UPA_LOG_T("%" PRIi64 " (%" PRIi64 ", %s) %s", frame_id, F->frame_id, state_to_str(F->state), point_to_str(P));
|
||||
|
||||
#define GET_INDEX_FROM_ID(RT, ID) ((uint64_t)(ID) % FRAME_COUNT)
|
||||
#define GET_INDEX_FROM_ID(RT, ID) ((int64_t)(ID) % FRAME_COUNT)
|
||||
|
||||
#define IIR_ALPHA_LT 0.8
|
||||
#define IIR_ALPHA_GT 0.8
|
||||
|
||||
static void
|
||||
do_iir_filter(uint64_t *target, double alpha_lt, double alpha_gt, uint64_t sample)
|
||||
do_iir_filter(int64_t *target, double alpha_lt, double alpha_gt, int64_t sample)
|
||||
{
|
||||
uint64_t t = *target;
|
||||
int64_t t = *target;
|
||||
double alpha = t < sample ? alpha_lt : alpha_gt;
|
||||
double a = time_ns_to_s(t) * alpha;
|
||||
double b = time_ns_to_s(sample) * (1.0 - alpha);
|
||||
*target = time_s_to_ns(a + b);
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
static int64_t
|
||||
min_period(const struct pacing_app *pa)
|
||||
{
|
||||
return pa->last_input.predicted_display_period_ns;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
static int64_t
|
||||
min_app_time(const struct pacing_app *pa)
|
||||
{
|
||||
return (uint64_t)(pa->min_app_time_ms.val * (double)U_TIME_1MS_IN_NS);
|
||||
return (int64_t)(pa->min_app_time_ms.val * (double)U_TIME_1MS_IN_NS);
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
static int64_t
|
||||
margin_time(const struct pacing_app *pa)
|
||||
{
|
||||
return (uint64_t)(pa->min_margin_ms.val * (double)U_TIME_1MS_IN_NS);
|
||||
return (int64_t)(pa->min_margin_ms.val * (double)U_TIME_1MS_IN_NS);
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
static int64_t
|
||||
last_sample_displayed(const struct pacing_app *pa)
|
||||
{
|
||||
return pa->last_input.predicted_display_time_ns;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
static int64_t
|
||||
last_return_predicted_display(const struct pacing_app *pa)
|
||||
{
|
||||
return pa->last_returned_ns;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
static int64_t
|
||||
total_app_time_ns(const struct pacing_app *pa)
|
||||
{
|
||||
uint64_t total_ns = pa->app.cpu_time_ns + pa->app.draw_time_ns + pa->app.gpu_time_ns;
|
||||
uint64_t min_ns = min_app_time(pa);
|
||||
int64_t total_ns = pa->app.cpu_time_ns + pa->app.draw_time_ns + pa->app.gpu_time_ns;
|
||||
int64_t min_ns = min_app_time(pa);
|
||||
|
||||
if (total_ns < min_ns) {
|
||||
total_ns = min_ns;
|
||||
|
@ -262,30 +262,30 @@ total_app_time_ns(const struct pacing_app *pa)
|
|||
return total_ns;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
static int64_t
|
||||
total_compositor_time_ns(const struct pacing_app *pa)
|
||||
{
|
||||
return margin_time(pa) + pa->last_input.extra_ns;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
static int64_t
|
||||
total_app_and_compositor_time_ns(const struct pacing_app *pa)
|
||||
{
|
||||
return total_app_time_ns(pa) + total_compositor_time_ns(pa);
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
static int64_t
|
||||
calc_period(const struct pacing_app *pa)
|
||||
{
|
||||
// Error checking.
|
||||
uint64_t base_period_ns = min_period(pa);
|
||||
int64_t base_period_ns = min_period(pa);
|
||||
if (base_period_ns == 0) {
|
||||
assert(false && "Have not yet received and samples from timing driver.");
|
||||
base_period_ns = U_TIME_1MS_IN_NS * 16; // Sure
|
||||
}
|
||||
|
||||
// Calculate the using both values separately.
|
||||
uint64_t period_ns = base_period_ns;
|
||||
int64_t period_ns = base_period_ns;
|
||||
while (pa->app.cpu_time_ns > period_ns) {
|
||||
period_ns += base_period_ns;
|
||||
}
|
||||
|
@ -301,15 +301,15 @@ calc_period(const struct pacing_app *pa)
|
|||
return period_ns;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
predict_display_time(const struct pacing_app *pa, uint64_t now_ns, uint64_t period_ns)
|
||||
static int64_t
|
||||
predict_display_time(const struct pacing_app *pa, int64_t now_ns, int64_t period_ns)
|
||||
{
|
||||
|
||||
// Total app and compositor time to produce a frame
|
||||
uint64_t app_and_compositor_time_ns = total_app_and_compositor_time_ns(pa);
|
||||
int64_t app_and_compositor_time_ns = total_app_and_compositor_time_ns(pa);
|
||||
|
||||
// Start from the last time that the driver displayed something.
|
||||
uint64_t val = last_sample_displayed(pa);
|
||||
int64_t val = last_sample_displayed(pa);
|
||||
|
||||
// Return a time after the last returned display time. Add half the
|
||||
// display period to the comparison for robustness when the last display
|
||||
|
@ -368,16 +368,16 @@ do_tracing(struct pacing_app *pa, struct u_pa_frame *f)
|
|||
}
|
||||
|
||||
#ifdef U_TRACE_TRACY // Uses Tracy specific things.
|
||||
uint64_t cpu_ns = f->when.begin_ns - f->when.wait_woke_ns;
|
||||
int64_t cpu_ns = f->when.begin_ns - f->when.wait_woke_ns;
|
||||
TracyCPlot("App CPU(ms)", time_ns_to_ms_f(cpu_ns));
|
||||
|
||||
uint64_t draw_ns = f->when.delivered_ns - f->when.begin_ns;
|
||||
int64_t draw_ns = f->when.delivered_ns - f->when.begin_ns;
|
||||
TracyCPlot("App Draw(ms)", time_ns_to_ms_f(draw_ns));
|
||||
|
||||
uint64_t gpu_ns = f->when.gpu_done_ns - f->when.delivered_ns;
|
||||
int64_t gpu_ns = f->when.gpu_done_ns - f->when.delivered_ns;
|
||||
TracyCPlot("App GPU(ms)", time_ns_to_ms_f(gpu_ns));
|
||||
|
||||
uint64_t frame_ns = f->when.gpu_done_ns - f->when.wait_woke_ns;
|
||||
int64_t frame_ns = f->when.gpu_done_ns - f->when.wait_woke_ns;
|
||||
TracyCPlot("App Frame(ms)", time_ns_to_ms_f(frame_ns));
|
||||
|
||||
int64_t wake_diff_ns = (int64_t)f->when.wait_woke_ns - (int64_t)f->predicted_wake_up_time_ns;
|
||||
|
@ -394,7 +394,7 @@ do_tracing(struct pacing_app *pa, struct u_pa_frame *f)
|
|||
TE_BEG(pa_cpu, f->when.predicted_ns, "sleep");
|
||||
TE_END(pa_cpu, f->when.wait_woke_ns);
|
||||
|
||||
uint64_t cpu_start_ns = f->when.wait_woke_ns + 1;
|
||||
int64_t cpu_start_ns = f->when.wait_woke_ns + 1;
|
||||
TE_BEG(pa_cpu, cpu_start_ns, "cpu");
|
||||
TE_END(pa_cpu, f->when.begin_ns);
|
||||
|
||||
|
@ -432,11 +432,11 @@ do_tracing(struct pacing_app *pa, struct u_pa_frame *f)
|
|||
|
||||
static void
|
||||
pa_predict(struct u_pacing_app *upa,
|
||||
uint64_t now_ns,
|
||||
int64_t now_ns,
|
||||
int64_t *out_frame_id,
|
||||
uint64_t *out_wake_up_time,
|
||||
uint64_t *out_predicted_display_time,
|
||||
uint64_t *out_predicted_display_period)
|
||||
int64_t *out_wake_up_time,
|
||||
int64_t *out_predicted_display_time,
|
||||
int64_t *out_predicted_display_period)
|
||||
{
|
||||
struct pacing_app *pa = pacing_app(upa);
|
||||
|
||||
|
@ -445,7 +445,7 @@ pa_predict(struct u_pacing_app *upa,
|
|||
|
||||
DEBUG_PRINT_ID(frame_id);
|
||||
|
||||
uint64_t period_ns;
|
||||
int64_t period_ns;
|
||||
|
||||
/*
|
||||
* We can either limit the application to a calculated frame rate that
|
||||
|
@ -458,13 +458,13 @@ pa_predict(struct u_pacing_app *upa,
|
|||
period_ns = calc_period(pa);
|
||||
}
|
||||
|
||||
uint64_t predict_ns = predict_display_time(pa, now_ns, period_ns);
|
||||
int64_t predict_ns = predict_display_time(pa, now_ns, period_ns);
|
||||
// How long we think the frame should take.
|
||||
uint64_t frame_time_ns = total_app_time_ns(pa);
|
||||
int64_t frame_time_ns = total_app_time_ns(pa);
|
||||
// When should the client wake up.
|
||||
uint64_t wake_up_time_ns = predict_ns - total_app_and_compositor_time_ns(pa);
|
||||
int64_t wake_up_time_ns = predict_ns - total_app_and_compositor_time_ns(pa);
|
||||
// When the client's GPU work should have completed.
|
||||
uint64_t gpu_done_time_ns = predict_ns - total_compositor_time_ns(pa);
|
||||
int64_t gpu_done_time_ns = predict_ns - total_compositor_time_ns(pa);
|
||||
|
||||
pa->last_returned_ns = predict_ns;
|
||||
|
||||
|
@ -492,7 +492,7 @@ pa_predict(struct u_pacing_app *upa,
|
|||
}
|
||||
|
||||
static void
|
||||
pa_mark_point(struct u_pacing_app *upa, int64_t frame_id, enum u_timing_point point, uint64_t when_ns)
|
||||
pa_mark_point(struct u_pacing_app *upa, int64_t frame_id, enum u_timing_point point, int64_t when_ns)
|
||||
{
|
||||
struct pacing_app *pa = pacing_app(upa);
|
||||
|
||||
|
@ -523,7 +523,7 @@ pa_mark_point(struct u_pacing_app *upa, int64_t frame_id, enum u_timing_point po
|
|||
}
|
||||
|
||||
static void
|
||||
pa_mark_discarded(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns)
|
||||
pa_mark_discarded(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns)
|
||||
{
|
||||
struct pacing_app *pa = pacing_app(upa);
|
||||
|
||||
|
@ -548,7 +548,7 @@ pa_mark_discarded(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns)
|
|||
}
|
||||
|
||||
static void
|
||||
pa_mark_delivered(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns, uint64_t display_time_ns)
|
||||
pa_mark_delivered(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns, int64_t display_time_ns)
|
||||
{
|
||||
struct pacing_app *pa = pacing_app(upa);
|
||||
|
||||
|
@ -567,7 +567,7 @@ pa_mark_delivered(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns,
|
|||
}
|
||||
|
||||
static void
|
||||
pa_mark_gpu_done(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns)
|
||||
pa_mark_gpu_done(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns)
|
||||
{
|
||||
struct pacing_app *pa = pacing_app(upa);
|
||||
|
||||
|
@ -595,9 +595,9 @@ pa_mark_gpu_done(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns)
|
|||
late = true;
|
||||
}
|
||||
|
||||
uint64_t diff_cpu_ns = f->when.begin_ns - f->when.wait_woke_ns;
|
||||
uint64_t diff_draw_ns = f->when.delivered_ns - f->when.begin_ns;
|
||||
uint64_t diff_gpu_ns = f->when.gpu_done_ns - f->when.delivered_ns;
|
||||
int64_t diff_cpu_ns = f->when.begin_ns - f->when.wait_woke_ns;
|
||||
int64_t diff_draw_ns = f->when.delivered_ns - f->when.begin_ns;
|
||||
int64_t diff_gpu_ns = f->when.gpu_done_ns - f->when.delivered_ns;
|
||||
|
||||
UPA_LOG_D(
|
||||
"Delivered frame %.2fms %s." //
|
||||
|
@ -628,7 +628,7 @@ pa_mark_gpu_done(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns)
|
|||
}
|
||||
|
||||
static void
|
||||
pa_latched(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns, int64_t system_frame_id)
|
||||
pa_latched(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns, int64_t system_frame_id)
|
||||
{
|
||||
struct pacing_app *pa = pacing_app(upa);
|
||||
|
||||
|
@ -652,7 +652,7 @@ pa_latched(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns, int64_t
|
|||
}
|
||||
|
||||
static void
|
||||
pa_retired(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns)
|
||||
pa_retired(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns)
|
||||
{
|
||||
struct pacing_app *pa = pacing_app(upa);
|
||||
|
||||
|
@ -673,9 +673,9 @@ pa_retired(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns)
|
|||
|
||||
static void
|
||||
pa_info(struct u_pacing_app *upa,
|
||||
uint64_t predicted_display_time_ns,
|
||||
uint64_t predicted_display_period_ns,
|
||||
uint64_t extra_ns)
|
||||
int64_t predicted_display_time_ns,
|
||||
int64_t predicted_display_period_ns,
|
||||
int64_t extra_ns)
|
||||
{
|
||||
struct pacing_app *pa = pacing_app(upa);
|
||||
|
||||
|
@ -732,9 +732,9 @@ pa_create(int64_t session_id, struct u_pacing_app **out_upa)
|
|||
u_var_add_root(pa, "App timing info", true);
|
||||
u_var_add_draggable_f32(pa, &pa->min_margin_ms, "Minimum margin(ms)");
|
||||
u_var_add_draggable_f32(pa, &pa->min_app_time_ms, "Minimum app time(ms)");
|
||||
u_var_add_ro_u64(pa, &pa->app.cpu_time_ns, "CPU time(ns)");
|
||||
u_var_add_ro_u64(pa, &pa->app.draw_time_ns, "Draw time(ns)");
|
||||
u_var_add_ro_u64(pa, &pa->app.gpu_time_ns, "GPU time(ns)");
|
||||
u_var_add_ro_i64(pa, &pa->app.cpu_time_ns, "CPU time(ns)");
|
||||
u_var_add_ro_i64(pa, &pa->app.draw_time_ns, "Draw time(ns)");
|
||||
u_var_add_ro_i64(pa, &pa->app.gpu_time_ns, "GPU time(ns)");
|
||||
|
||||
*out_upa = &pa->base;
|
||||
|
||||
|
|
|
@ -56,33 +56,33 @@ struct frame
|
|||
int64_t frame_id;
|
||||
|
||||
//! When this frame was last used for a prediction. Set in `predict_next_frame`.
|
||||
uint64_t when_predict_ns;
|
||||
int64_t when_predict_ns;
|
||||
|
||||
//! When should the compositor wake up. Set in `predict_next_frame`.
|
||||
uint64_t wake_up_time_ns;
|
||||
int64_t wake_up_time_ns;
|
||||
|
||||
//! When we last woke up the compositor after its equivalent of wait_frame. Set in `pc_mark_point` with
|
||||
//! `U_TIMING_POINT_WAKE_UP`.
|
||||
uint64_t when_woke_ns;
|
||||
int64_t when_woke_ns;
|
||||
|
||||
//! When the compositor started rendering a frame
|
||||
uint64_t when_began_ns;
|
||||
int64_t when_began_ns;
|
||||
|
||||
//! When the compositor finished rendering a frame
|
||||
uint64_t when_submitted_ns;
|
||||
int64_t when_submitted_ns;
|
||||
|
||||
//! When new frame timing info was last added.
|
||||
uint64_t when_infoed_ns;
|
||||
int64_t when_infoed_ns;
|
||||
|
||||
//! How much time we currently expect the compositor to take rendering a frame. Updated in `predict_next_frame`
|
||||
uint64_t current_comp_time_ns;
|
||||
int64_t current_comp_time_ns;
|
||||
|
||||
uint64_t expected_done_time_ns; //!< When we expect the compositor to be done with its frame.
|
||||
uint64_t desired_present_time_ns; //!< The GPU should start scanning out at this time.
|
||||
uint64_t predicted_display_time_ns; //!< At what time have we predicted that pixels turns to photons.
|
||||
uint64_t present_margin_ns;
|
||||
uint64_t actual_present_time_ns;
|
||||
uint64_t earliest_present_time_ns;
|
||||
int64_t expected_done_time_ns; //!< When we expect the compositor to be done with its frame.
|
||||
int64_t desired_present_time_ns; //!< The GPU should start scanning out at this time.
|
||||
int64_t predicted_display_time_ns; //!< At what time have we predicted that pixels turns to photons.
|
||||
int64_t present_margin_ns;
|
||||
int64_t actual_present_time_ns;
|
||||
int64_t earliest_present_time_ns;
|
||||
|
||||
enum frame_state state;
|
||||
};
|
||||
|
@ -96,17 +96,17 @@ struct pacing_compositor
|
|||
* the display engine starts scanning out from the buffers we provided,
|
||||
* and not when the pixels turned into photons that the user sees.
|
||||
*/
|
||||
uint64_t present_to_display_offset_ns;
|
||||
int64_t present_to_display_offset_ns;
|
||||
|
||||
/*!
|
||||
* Frame period of the device.
|
||||
*/
|
||||
uint64_t frame_period_ns;
|
||||
int64_t frame_period_ns;
|
||||
|
||||
/*!
|
||||
* The amount of time that the compositor needs to render frame.
|
||||
*/
|
||||
uint64_t comp_time_ns;
|
||||
int64_t comp_time_ns;
|
||||
|
||||
/*!
|
||||
* Used to generate frame IDs.
|
||||
|
@ -116,23 +116,23 @@ struct pacing_compositor
|
|||
/*!
|
||||
* The maximum amount we give to the compositor.
|
||||
*/
|
||||
uint64_t comp_time_max_ns;
|
||||
int64_t comp_time_max_ns;
|
||||
|
||||
/*!
|
||||
* If we missed a frame, back off this much.
|
||||
*/
|
||||
uint64_t adjust_missed_ns;
|
||||
int64_t adjust_missed_ns;
|
||||
|
||||
/*!
|
||||
* Adjustment of time if we didn't miss the frame,
|
||||
* also used as range to stay around timing target.
|
||||
*/
|
||||
uint64_t adjust_non_miss_ns;
|
||||
int64_t adjust_non_miss_ns;
|
||||
|
||||
/*!
|
||||
* Extra time between end of draw time and when the present happens.
|
||||
*/
|
||||
uint64_t margin_ns;
|
||||
int64_t margin_ns;
|
||||
|
||||
/*!
|
||||
* Frame store.
|
||||
|
@ -159,34 +159,34 @@ ns_to_ms(int64_t t)
|
|||
return (double)(t / 1000) / 1000.0;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
get_percent_of_time(uint64_t time_ns, uint32_t fraction_percent)
|
||||
static int64_t
|
||||
get_percent_of_time(int64_t time_ns, uint32_t fraction_percent)
|
||||
{
|
||||
double fraction = (double)fraction_percent / 100.0;
|
||||
return time_s_to_ns(time_ns_to_s(time_ns) * fraction);
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
static int64_t
|
||||
calc_total_comp_time(struct pacing_compositor *pc)
|
||||
{
|
||||
return pc->comp_time_ns + pc->margin_ns;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
calc_display_time_from_present_time(struct pacing_compositor *pc, uint64_t desired_present_time_ns)
|
||||
static int64_t
|
||||
calc_display_time_from_present_time(struct pacing_compositor *pc, int64_t desired_present_time_ns)
|
||||
{
|
||||
return desired_present_time_ns + pc->present_to_display_offset_ns;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_within_of_each_other(uint64_t l, uint64_t r, uint64_t range)
|
||||
is_within_of_each_other(int64_t l, int64_t r, int64_t range)
|
||||
{
|
||||
int64_t t = (int64_t)l - (int64_t)r;
|
||||
return (-(int64_t)range < t) && (t < (int64_t)range);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_within_half_ms(uint64_t l, uint64_t r)
|
||||
is_within_half_ms(int64_t l, int64_t r)
|
||||
{
|
||||
return is_within_of_each_other(l, r, U_TIME_HALF_MS_IN_NS);
|
||||
}
|
||||
|
@ -238,8 +238,8 @@ create_frame(struct pacing_compositor *pc, enum frame_state state)
|
|||
static struct frame *
|
||||
get_latest_frame_with_state_at_least(struct pacing_compositor *pc, enum frame_state state)
|
||||
{
|
||||
uint64_t start_from = pc->next_frame_id;
|
||||
uint64_t count = 1;
|
||||
int64_t start_from = pc->next_frame_id;
|
||||
int64_t count = 1;
|
||||
|
||||
while (start_from >= count && count < NUM_FRAMES) {
|
||||
int64_t frame_id = start_from - count;
|
||||
|
@ -258,12 +258,12 @@ get_latest_frame_with_state_at_least(struct pacing_compositor *pc, enum frame_st
|
|||
* initialize frame::desired_present_time_ns (with a crude estimate) and frame::when_predict_ns.
|
||||
*/
|
||||
static struct frame *
|
||||
do_clean_slate_frame(struct pacing_compositor *pc, uint64_t now_ns)
|
||||
do_clean_slate_frame(struct pacing_compositor *pc, int64_t now_ns)
|
||||
{
|
||||
struct frame *f = create_frame(pc, STATE_PREDICTED);
|
||||
|
||||
// Wild shot in the dark.
|
||||
uint64_t the_time_ns = now_ns + pc->frame_period_ns * 10;
|
||||
int64_t the_time_ns = now_ns + pc->frame_period_ns * 10;
|
||||
f->when_predict_ns = now_ns;
|
||||
f->desired_present_time_ns = the_time_ns;
|
||||
|
||||
|
@ -275,11 +275,11 @@ do_clean_slate_frame(struct pacing_compositor *pc, uint64_t now_ns)
|
|||
* prediction in it.
|
||||
*/
|
||||
static struct frame *
|
||||
walk_forward_through_frames(struct pacing_compositor *pc, uint64_t last_present_time_ns, uint64_t now_ns)
|
||||
walk_forward_through_frames(struct pacing_compositor *pc, int64_t last_present_time_ns, int64_t now_ns)
|
||||
{
|
||||
// This is the earliest possible time we could present, assuming rendering still must take place.
|
||||
uint64_t from_time_ns = now_ns + calc_total_comp_time(pc);
|
||||
uint64_t desired_present_time_ns = last_present_time_ns + pc->frame_period_ns;
|
||||
int64_t from_time_ns = now_ns + calc_total_comp_time(pc);
|
||||
int64_t desired_present_time_ns = last_present_time_ns + pc->frame_period_ns;
|
||||
|
||||
while (desired_present_time_ns <= from_time_ns) {
|
||||
UPC_LOG_D(
|
||||
|
@ -303,7 +303,7 @@ walk_forward_through_frames(struct pacing_compositor *pc, uint64_t last_present_
|
|||
}
|
||||
|
||||
static struct frame *
|
||||
predict_next_frame(struct pacing_compositor *pc, uint64_t now_ns)
|
||||
predict_next_frame(struct pacing_compositor *pc, int64_t now_ns)
|
||||
{
|
||||
struct frame *f = NULL;
|
||||
// Last earliest display time, can be zero.
|
||||
|
@ -320,7 +320,7 @@ predict_next_frame(struct pacing_compositor *pc, uint64_t now_ns)
|
|||
|
||||
int64_t diff_id = last_predicted->frame_id - last_completed->frame_id;
|
||||
int64_t diff_ns = last_completed->desired_present_time_ns - last_completed->earliest_present_time_ns;
|
||||
uint64_t adjusted_last_present_time_ns =
|
||||
int64_t adjusted_last_present_time_ns =
|
||||
last_completed->earliest_present_time_ns + diff_id * pc->frame_period_ns;
|
||||
|
||||
if (diff_ns > U_TIME_1MS_IN_NS) {
|
||||
|
@ -356,7 +356,7 @@ predict_next_frame(struct pacing_compositor *pc, uint64_t now_ns)
|
|||
static void
|
||||
adjust_comp_time(struct pacing_compositor *pc, struct frame *f)
|
||||
{
|
||||
uint64_t comp_time_ns = pc->comp_time_ns;
|
||||
int64_t comp_time_ns = pc->comp_time_ns;
|
||||
|
||||
if (f->actual_present_time_ns > f->desired_present_time_ns &&
|
||||
!is_within_half_ms(f->actual_present_time_ns, f->desired_present_time_ns)) {
|
||||
|
@ -448,7 +448,7 @@ do_tracing(struct pacing_compositor *pc, struct frame *f)
|
|||
TE_BEG(pc_cpu, f->when_predict_ns, "sleep");
|
||||
TE_END(pc_cpu, f->wake_up_time_ns);
|
||||
|
||||
uint64_t oversleep_start_ns = f->wake_up_time_ns + 1;
|
||||
int64_t oversleep_start_ns = f->wake_up_time_ns + 1;
|
||||
if (f->when_woke_ns > oversleep_start_ns) {
|
||||
TE_BEG(pc_cpu, oversleep_start_ns, "oversleep");
|
||||
TE_END(pc_cpu, f->when_woke_ns);
|
||||
|
@ -461,7 +461,7 @@ do_tracing(struct pacing_compositor *pc, struct frame *f)
|
|||
*
|
||||
*/
|
||||
|
||||
uint64_t gpu_end_ns = f->actual_present_time_ns - f->present_margin_ns;
|
||||
int64_t gpu_end_ns = f->actual_present_time_ns - f->present_margin_ns;
|
||||
if (gpu_end_ns > f->when_submitted_ns) {
|
||||
TE_BEG(pc_gpu, f->when_submitted_ns, "gpu");
|
||||
TE_END(pc_gpu, gpu_end_ns);
|
||||
|
@ -553,25 +553,25 @@ do_tracing(struct pacing_compositor *pc, struct frame *f)
|
|||
|
||||
static void
|
||||
pc_predict(struct u_pacing_compositor *upc,
|
||||
uint64_t now_ns,
|
||||
int64_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)
|
||||
int64_t *out_wake_up_time_ns,
|
||||
int64_t *out_desired_present_time_ns,
|
||||
int64_t *out_present_slop_ns,
|
||||
int64_t *out_predicted_display_time_ns,
|
||||
int64_t *out_predicted_display_period_ns,
|
||||
int64_t *out_min_display_period_ns)
|
||||
{
|
||||
struct pacing_compositor *pc = pacing_compositor(upc);
|
||||
|
||||
struct frame *f = predict_next_frame(pc, now_ns);
|
||||
|
||||
uint64_t wake_up_time_ns = f->wake_up_time_ns;
|
||||
uint64_t desired_present_time_ns = f->desired_present_time_ns;
|
||||
uint64_t present_slop_ns = PRESENT_SLOP_NS;
|
||||
uint64_t predicted_display_time_ns = f->predicted_display_time_ns;
|
||||
uint64_t predicted_display_period_ns = pc->frame_period_ns;
|
||||
uint64_t min_display_period_ns = pc->frame_period_ns;
|
||||
int64_t wake_up_time_ns = f->wake_up_time_ns;
|
||||
int64_t desired_present_time_ns = f->desired_present_time_ns;
|
||||
int64_t present_slop_ns = PRESENT_SLOP_NS;
|
||||
int64_t predicted_display_time_ns = f->predicted_display_time_ns;
|
||||
int64_t predicted_display_period_ns = pc->frame_period_ns;
|
||||
int64_t min_display_period_ns = pc->frame_period_ns;
|
||||
|
||||
*out_frame_id = f->frame_id;
|
||||
*out_wake_up_time_ns = wake_up_time_ns;
|
||||
|
@ -583,7 +583,7 @@ pc_predict(struct u_pacing_compositor *upc,
|
|||
}
|
||||
|
||||
static void
|
||||
pc_mark_point(struct u_pacing_compositor *upc, enum u_timing_point point, int64_t frame_id, uint64_t when_ns)
|
||||
pc_mark_point(struct u_pacing_compositor *upc, enum u_timing_point point, int64_t frame_id, int64_t when_ns)
|
||||
{
|
||||
struct pacing_compositor *pc = pacing_compositor(upc);
|
||||
struct frame *f = get_frame(pc, frame_id);
|
||||
|
@ -622,11 +622,11 @@ pc_mark_point(struct u_pacing_compositor *upc, enum u_timing_point point, int64_
|
|||
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)
|
||||
int64_t desired_present_time_ns,
|
||||
int64_t actual_present_time_ns,
|
||||
int64_t earliest_present_time_ns,
|
||||
int64_t present_margin_ns,
|
||||
int64_t when_ns)
|
||||
{
|
||||
struct pacing_compositor *pc = pacing_compositor(upc);
|
||||
(void)pc;
|
||||
|
@ -642,7 +642,7 @@ pc_info(struct u_pacing_compositor *upc,
|
|||
}
|
||||
|
||||
assert(f->state == STATE_SUBMITTED);
|
||||
XRT_MAYBE_UNUSED uint64_t unslopped_desired_present_time_ns = desired_present_time_ns + PRESENT_SLOP_NS;
|
||||
XRT_MAYBE_UNUSED int64_t unslopped_desired_present_time_ns = desired_present_time_ns + PRESENT_SLOP_NS;
|
||||
assert(f->desired_present_time_ns == desired_present_time_ns ||
|
||||
f->desired_present_time_ns == unslopped_desired_present_time_ns);
|
||||
|
||||
|
@ -652,7 +652,7 @@ pc_info(struct u_pacing_compositor *upc,
|
|||
f->present_margin_ns = present_margin_ns;
|
||||
f->state = STATE_INFO;
|
||||
|
||||
uint64_t since_last_frame_ns = 0;
|
||||
int64_t since_last_frame_ns = 0;
|
||||
if (last != NULL) {
|
||||
since_last_frame_ns = f->desired_present_time_ns - last->desired_present_time_ns;
|
||||
}
|
||||
|
@ -695,7 +695,7 @@ pc_info(struct u_pacing_compositor *upc,
|
|||
|
||||
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)
|
||||
struct u_pacing_compositor *upc, int64_t frame_id, int64_t gpu_start_ns, int64_t gpu_end_ns, int64_t when_ns)
|
||||
{
|
||||
if (u_metrics_is_active()) {
|
||||
struct u_metrics_system_gpu_info umgi = {
|
||||
|
@ -710,7 +710,7 @@ pc_info_gpu(
|
|||
}
|
||||
|
||||
static void
|
||||
pc_update_vblank_from_display_control(struct u_pacing_compositor *upc, uint64_t last_vblank_ns)
|
||||
pc_update_vblank_from_display_control(struct u_pacing_compositor *upc, int64_t last_vblank_ns)
|
||||
{
|
||||
/*
|
||||
* This is a no-op, here in case display control is used at the
|
||||
|
@ -719,7 +719,7 @@ pc_update_vblank_from_display_control(struct u_pacing_compositor *upc, uint64_t
|
|||
}
|
||||
|
||||
static void
|
||||
pc_update_present_offset(struct u_pacing_compositor *upc, int64_t frame_id, uint64_t present_to_display_offset_ns)
|
||||
pc_update_present_offset(struct u_pacing_compositor *upc, int64_t frame_id, int64_t present_to_display_offset_ns)
|
||||
{
|
||||
struct pacing_compositor *pc = pacing_compositor(upc);
|
||||
|
||||
|
@ -750,7 +750,7 @@ const struct u_pc_display_timing_config U_PC_DISPLAY_TIMING_CONFIG_DEFAULT = {
|
|||
};
|
||||
|
||||
xrt_result_t
|
||||
u_pc_display_timing_create(uint64_t estimated_frame_period_ns,
|
||||
u_pc_display_timing_create(int64_t estimated_frame_period_ns,
|
||||
const struct u_pc_display_timing_config *config,
|
||||
struct u_pacing_compositor **out_upc)
|
||||
{
|
||||
|
|
|
@ -45,44 +45,44 @@ struct frame
|
|||
int64_t frame_id;
|
||||
|
||||
//! When should the compositor wake up. Set in `pc_predict`.
|
||||
uint64_t predicted_wake_up_time_ns;
|
||||
int64_t predicted_wake_up_time_ns;
|
||||
|
||||
//! When should the compositor present the frame.
|
||||
uint64_t predicted_present_time_ns;
|
||||
int64_t predicted_present_time_ns;
|
||||
|
||||
//! When should the frame be displayed.
|
||||
uint64_t predicted_display_time_ns;
|
||||
int64_t predicted_display_time_ns;
|
||||
|
||||
//! The period that the pacer used for this frame.
|
||||
uint64_t predicted_display_period_ns;
|
||||
int64_t predicted_display_period_ns;
|
||||
|
||||
//! When this frame was last used for a prediction. Set in `pc_predict`.
|
||||
uint64_t when_predict_ns;
|
||||
int64_t when_predict_ns;
|
||||
|
||||
/*!
|
||||
* When the compositor woke up after its equivalent of wait_frame.
|
||||
* Set in `pc_mark_point` with `U_TIMING_POINT_WAKE_UP`.
|
||||
*/
|
||||
uint64_t when_woke_ns;
|
||||
int64_t when_woke_ns;
|
||||
|
||||
/*!
|
||||
* When the compositor began rendering a frame. Set in `pc_mark_point`
|
||||
* with `U_TIMING_POINT_BEGIN`.
|
||||
*/
|
||||
uint64_t when_began_ns;
|
||||
int64_t when_began_ns;
|
||||
|
||||
/*!
|
||||
* When the compositor began submitting the work to the GPU, after
|
||||
* it completed building the command buffers. Set in `pc_mark_point`
|
||||
* with `U_TIMING_POINT_SUBMIT_BEGIN`.
|
||||
*/
|
||||
uint64_t when_submit_began_ns;
|
||||
int64_t when_submit_began_ns;
|
||||
|
||||
/*!
|
||||
* When the compositor completed submitting the work to the GPU. Set in
|
||||
* `pc_mark_point` with `U_TIMING_POINT_SUBMIT_END`.
|
||||
*/
|
||||
uint64_t when_submit_end_ns;
|
||||
int64_t when_submit_end_ns;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
@ -97,12 +97,12 @@ struct fake_timing
|
|||
/*!
|
||||
* The periodicity of the display.
|
||||
*/
|
||||
uint64_t frame_period_ns;
|
||||
int64_t frame_period_ns;
|
||||
|
||||
/*!
|
||||
* When the last frame was presented, not displayed.
|
||||
*/
|
||||
uint64_t last_present_time_ns;
|
||||
int64_t last_present_time_ns;
|
||||
|
||||
/*!
|
||||
* Very often the present time that we get from the system is only when
|
||||
|
@ -112,7 +112,7 @@ struct fake_timing
|
|||
struct u_var_draggable_f32 present_to_display_offset_ms;
|
||||
|
||||
//! The amount of time that the application needs to render frame.
|
||||
uint64_t comp_time_ns;
|
||||
int64_t comp_time_ns;
|
||||
|
||||
//! This won't run out, trust me.
|
||||
int64_t frame_id_generator;
|
||||
|
@ -165,11 +165,11 @@ get_new_frame(struct fake_timing *ft)
|
|||
return f;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
predict_next_frame_present_time(struct fake_timing *ft, uint64_t now_ns)
|
||||
static int64_t
|
||||
predict_next_frame_present_time(struct fake_timing *ft, int64_t now_ns)
|
||||
{
|
||||
uint64_t time_needed_ns = ft->comp_time_ns;
|
||||
uint64_t predicted_present_time_ns = ft->last_present_time_ns + ft->frame_period_ns;
|
||||
int64_t time_needed_ns = ft->comp_time_ns;
|
||||
int64_t predicted_present_time_ns = ft->last_present_time_ns + ft->frame_period_ns;
|
||||
|
||||
while (now_ns + time_needed_ns > predicted_present_time_ns) {
|
||||
predicted_present_time_ns += ft->frame_period_ns;
|
||||
|
@ -178,16 +178,16 @@ predict_next_frame_present_time(struct fake_timing *ft, uint64_t now_ns)
|
|||
return predicted_present_time_ns;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
calc_display_time(struct fake_timing *ft, uint64_t present_time_ns)
|
||||
static int64_t
|
||||
calc_display_time(struct fake_timing *ft, int64_t present_time_ns)
|
||||
{
|
||||
double offset_ms = ft->present_to_display_offset_ms.val;
|
||||
uint64_t offset_ns = time_ms_f_to_ns(offset_ms);
|
||||
int64_t offset_ns = time_ms_f_to_ns(offset_ms);
|
||||
return present_time_ns + offset_ns;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
get_percent_of_time(uint64_t time_ns, uint32_t fraction_percent)
|
||||
static int64_t
|
||||
get_percent_of_time(int64_t time_ns, uint32_t fraction_percent)
|
||||
{
|
||||
double fraction = (double)fraction_percent / 100.0;
|
||||
return time_s_to_ns(time_ns_to_s(time_ns) * fraction);
|
||||
|
@ -224,9 +224,9 @@ calc_frame_stats(struct fake_timing *ft, struct frame *f)
|
|||
return;
|
||||
}
|
||||
|
||||
uint64_t cpu_ns = f->when_began_ns - f->when_woke_ns;
|
||||
uint64_t draw_ns = f->when_submit_began_ns - f->when_began_ns;
|
||||
uint64_t submit_ns = f->when_submit_end_ns - f->when_submit_began_ns;
|
||||
int64_t cpu_ns = f->when_began_ns - f->when_woke_ns;
|
||||
int64_t draw_ns = f->when_submit_began_ns - f->when_began_ns;
|
||||
int64_t submit_ns = f->when_submit_end_ns - f->when_submit_began_ns;
|
||||
|
||||
bool full = false;
|
||||
full |= u_ls_ns_add(&ft->cpu, cpu_ns);
|
||||
|
@ -239,16 +239,16 @@ calc_frame_stats(struct fake_timing *ft, struct frame *f)
|
|||
}
|
||||
|
||||
static void
|
||||
calc_gpu_stats(struct fake_timing *ft, struct frame *f, uint64_t gpu_start_ns, uint64_t gpu_end_ns)
|
||||
calc_gpu_stats(struct fake_timing *ft, struct frame *f, int64_t gpu_start_ns, int64_t gpu_end_ns)
|
||||
{
|
||||
if (!debug_get_bool_option_live_stats()) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t then_ns = f->when_submit_began_ns;
|
||||
uint64_t delay_ns = gpu_start_ns > then_ns ? gpu_start_ns - then_ns : 0;
|
||||
uint64_t gpu_ns = gpu_end_ns - gpu_start_ns;
|
||||
uint64_t frame_ns = gpu_end_ns - f->when_woke_ns;
|
||||
int64_t then_ns = f->when_submit_began_ns;
|
||||
int64_t delay_ns = gpu_start_ns > then_ns ? gpu_start_ns - then_ns : 0;
|
||||
int64_t gpu_ns = gpu_end_ns - gpu_start_ns;
|
||||
int64_t frame_ns = gpu_end_ns - f->when_woke_ns;
|
||||
|
||||
bool full = false;
|
||||
full |= u_ls_ns_add(&ft->gpu, gpu_ns);
|
||||
|
@ -269,27 +269,27 @@ calc_gpu_stats(struct fake_timing *ft, struct frame *f, uint64_t gpu_start_ns, u
|
|||
|
||||
static void
|
||||
pc_predict(struct u_pacing_compositor *upc,
|
||||
uint64_t now_ns,
|
||||
int64_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)
|
||||
int64_t *out_wake_up_time_ns,
|
||||
int64_t *out_desired_present_time_ns,
|
||||
int64_t *out_present_slop_ns,
|
||||
int64_t *out_predicted_display_time_ns,
|
||||
int64_t *out_predicted_display_period_ns,
|
||||
int64_t *out_min_display_period_ns)
|
||||
{
|
||||
struct fake_timing *ft = fake_timing(upc);
|
||||
|
||||
struct frame *f = get_new_frame(ft);
|
||||
|
||||
int64_t frame_id = f->frame_id;
|
||||
uint64_t desired_present_time_ns = predict_next_frame_present_time(ft, now_ns);
|
||||
uint64_t predicted_display_time_ns = calc_display_time(ft, desired_present_time_ns);
|
||||
int64_t desired_present_time_ns = predict_next_frame_present_time(ft, now_ns);
|
||||
int64_t predicted_display_time_ns = calc_display_time(ft, desired_present_time_ns);
|
||||
|
||||
uint64_t wake_up_time_ns = desired_present_time_ns - ft->comp_time_ns;
|
||||
uint64_t present_slop_ns = U_TIME_HALF_MS_IN_NS;
|
||||
uint64_t predicted_display_period_ns = ft->frame_period_ns;
|
||||
uint64_t min_display_period_ns = ft->frame_period_ns;
|
||||
int64_t wake_up_time_ns = desired_present_time_ns - ft->comp_time_ns;
|
||||
int64_t present_slop_ns = U_TIME_HALF_MS_IN_NS;
|
||||
int64_t predicted_display_period_ns = ft->frame_period_ns;
|
||||
int64_t min_display_period_ns = ft->frame_period_ns;
|
||||
|
||||
// Set the frame info.
|
||||
f->predicted_wake_up_time_ns = wake_up_time_ns;
|
||||
|
@ -322,7 +322,7 @@ pc_predict(struct u_pacing_compositor *upc,
|
|||
}
|
||||
|
||||
static void
|
||||
pc_mark_point(struct u_pacing_compositor *upc, enum u_timing_point point, int64_t frame_id, uint64_t when_ns)
|
||||
pc_mark_point(struct u_pacing_compositor *upc, enum u_timing_point point, int64_t frame_id, int64_t when_ns)
|
||||
{
|
||||
struct fake_timing *ft = fake_timing(upc);
|
||||
struct frame *f = get_frame_or_null(ft, frame_id);
|
||||
|
@ -348,11 +348,11 @@ pc_mark_point(struct u_pacing_compositor *upc, enum u_timing_point point, int64_
|
|||
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)
|
||||
int64_t desired_present_time_ns,
|
||||
int64_t actual_present_time_ns,
|
||||
int64_t earliest_present_time_ns,
|
||||
int64_t present_margin_ns,
|
||||
int64_t when_ns)
|
||||
{
|
||||
/*
|
||||
* The compositor might call this function because it selected the
|
||||
|
@ -362,7 +362,7 @@ pc_info(struct u_pacing_compositor *upc,
|
|||
|
||||
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)
|
||||
struct u_pacing_compositor *upc, int64_t frame_id, int64_t gpu_start_ns, int64_t gpu_end_ns, int64_t when_ns)
|
||||
{
|
||||
struct fake_timing *ft = fake_timing(upc);
|
||||
|
||||
|
@ -396,13 +396,13 @@ pc_info_gpu(
|
|||
#endif
|
||||
|
||||
#ifdef U_TRACE_TRACY
|
||||
uint64_t diff_ns = gpu_end_ns - gpu_start_ns;
|
||||
int64_t diff_ns = gpu_end_ns - gpu_start_ns;
|
||||
TracyCPlot("Compositor GPU(ms)", time_ns_to_ms_f(diff_ns));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
pc_update_vblank_from_display_control(struct u_pacing_compositor *upc, uint64_t last_vblank_ns)
|
||||
pc_update_vblank_from_display_control(struct u_pacing_compositor *upc, int64_t last_vblank_ns)
|
||||
{
|
||||
struct fake_timing *ft = fake_timing(upc);
|
||||
|
||||
|
@ -411,7 +411,7 @@ pc_update_vblank_from_display_control(struct u_pacing_compositor *upc, uint64_t
|
|||
}
|
||||
|
||||
static void
|
||||
pc_update_present_offset(struct u_pacing_compositor *upc, int64_t frame_id, uint64_t present_to_display_offset_ns)
|
||||
pc_update_present_offset(struct u_pacing_compositor *upc, int64_t frame_id, int64_t present_to_display_offset_ns)
|
||||
{
|
||||
struct fake_timing *ft = fake_timing(upc);
|
||||
|
||||
|
@ -441,7 +441,7 @@ pc_destroy(struct u_pacing_compositor *upc)
|
|||
*/
|
||||
|
||||
xrt_result_t
|
||||
u_pc_fake_create(uint64_t estimated_frame_period_ns, uint64_t now_ns, struct u_pacing_compositor **out_upc)
|
||||
u_pc_fake_create(int64_t estimated_frame_period_ns, int64_t now_ns, struct u_pacing_compositor **out_upc)
|
||||
{
|
||||
struct fake_timing *ft = U_TYPED_CALLOC(struct fake_timing);
|
||||
ft->base.predict = pc_predict;
|
||||
|
@ -479,7 +479,7 @@ u_pc_fake_create(uint64_t estimated_frame_period_ns, uint64_t now_ns, struct u_p
|
|||
|
||||
// Or at least a certain amount of time.
|
||||
float min_comp_time_ms_f = debug_get_float_option_min_comp_time_ms();
|
||||
uint64_t min_comp_time_ns = time_ms_f_to_ns(min_comp_time_ms_f);
|
||||
int64_t min_comp_time_ns = time_ms_f_to_ns(min_comp_time_ms_f);
|
||||
|
||||
if (ft->comp_time_ns < min_comp_time_ns) {
|
||||
ft->comp_time_ns = min_comp_time_ns;
|
||||
|
@ -491,9 +491,9 @@ u_pc_fake_create(uint64_t estimated_frame_period_ns, uint64_t now_ns, struct u_p
|
|||
// U variable tracking.
|
||||
u_var_add_root(ft, "Compositor timing info", true);
|
||||
u_var_add_draggable_f32(ft, &ft->present_to_display_offset_ms, "Present to display offset(ms)");
|
||||
u_var_add_ro_u64(ft, &ft->frame_period_ns, "Frame period(ns)");
|
||||
u_var_add_ro_u64(ft, &ft->comp_time_ns, "Compositor time(ns)");
|
||||
u_var_add_ro_u64(ft, &ft->last_present_time_ns, "Last present time(ns)");
|
||||
u_var_add_ro_i64(ft, &ft->frame_period_ns, "Frame period(ns)");
|
||||
u_var_add_ro_i64(ft, &ft->comp_time_ns, "Compositor time(ns)");
|
||||
u_var_add_ro_i64(ft, &ft->last_present_time_ns, "Last present time(ns)");
|
||||
|
||||
// Return value.
|
||||
*out_upc = &ft->base;
|
||||
|
|
|
@ -25,8 +25,8 @@ static constexpr unanoseconds frame_interval_ns(16ms);
|
|||
|
||||
namespace {
|
||||
|
||||
uint64_t
|
||||
getNextPresentAfterTimestampAndKnownPresent(uint64_t timestamp_ns, uint64_t known_present_ns)
|
||||
int64_t
|
||||
getNextPresentAfterTimestampAndKnownPresent(int64_t timestamp_ns, int64_t known_present_ns)
|
||||
{
|
||||
|
||||
while (known_present_ns < timestamp_ns) {
|
||||
|
@ -34,8 +34,8 @@ getNextPresentAfterTimestampAndKnownPresent(uint64_t timestamp_ns, uint64_t know
|
|||
}
|
||||
return known_present_ns;
|
||||
}
|
||||
uint64_t
|
||||
getPresentBefore(uint64_t timestamp_ns, uint64_t known_present_ns)
|
||||
int64_t
|
||||
getPresentBefore(int64_t timestamp_ns, int64_t known_present_ns)
|
||||
{
|
||||
|
||||
while (known_present_ns >= timestamp_ns && known_present_ns > frame_interval_ns.count()) {
|
||||
|
@ -43,8 +43,8 @@ getPresentBefore(uint64_t timestamp_ns, uint64_t known_present_ns)
|
|||
}
|
||||
return known_present_ns;
|
||||
}
|
||||
uint64_t
|
||||
getNextPresentAfterTimestamp(uint64_t timestamp_ns, uint64_t known_present_ns)
|
||||
int64_t
|
||||
getNextPresentAfterTimestamp(int64_t timestamp_ns, int64_t known_present_ns)
|
||||
{
|
||||
auto present_before_ns = getPresentBefore(timestamp_ns, known_present_ns);
|
||||
return getNextPresentAfterTimestampAndKnownPresent(timestamp_ns, present_before_ns);
|
||||
|
@ -53,17 +53,17 @@ getNextPresentAfterTimestamp(uint64_t timestamp_ns, uint64_t known_present_ns)
|
|||
struct CompositorPredictions
|
||||
{
|
||||
int64_t frame_id{0};
|
||||
uint64_t wake_up_time_ns{0};
|
||||
uint64_t desired_present_time_ns{0};
|
||||
uint64_t present_slop_ns{0};
|
||||
uint64_t predicted_display_time_ns{0};
|
||||
uint64_t predicted_display_period_ns{0};
|
||||
uint64_t min_display_period_ns{0};
|
||||
int64_t wake_up_time_ns{0};
|
||||
int64_t desired_present_time_ns{0};
|
||||
int64_t present_slop_ns{0};
|
||||
int64_t predicted_display_time_ns{0};
|
||||
int64_t predicted_display_period_ns{0};
|
||||
int64_t min_display_period_ns{0};
|
||||
};
|
||||
} // namespace
|
||||
|
||||
static void
|
||||
basicPredictionConsistencyChecks(uint64_t now_ns, CompositorPredictions const &predictions)
|
||||
basicPredictionConsistencyChecks(int64_t now_ns, CompositorPredictions const &predictions)
|
||||
{
|
||||
INFO(predictions.frame_id);
|
||||
INFO(now_ns);
|
||||
|
@ -79,7 +79,7 @@ basicPredictionConsistencyChecks(uint64_t now_ns, CompositorPredictions const &p
|
|||
|
||||
struct SimulatedDisplayTimingData
|
||||
{
|
||||
SimulatedDisplayTimingData(int64_t id, uint64_t desired_present_time, uint64_t gpu_finish, uint64_t now)
|
||||
SimulatedDisplayTimingData(int64_t id, int64_t desired_present_time, int64_t gpu_finish, int64_t now)
|
||||
: frame_id(id), desired_present_time_ns(desired_present_time),
|
||||
actual_present_time_ns(getNextPresentAfterTimestampAndKnownPresent(gpu_finish, desired_present_time)),
|
||||
earliest_present_time_ns(getNextPresentAfterTimestamp(gpu_finish, desired_present_time)),
|
||||
|
@ -87,11 +87,11 @@ struct SimulatedDisplayTimingData
|
|||
{}
|
||||
|
||||
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 now_ns;
|
||||
int64_t desired_present_time_ns;
|
||||
int64_t actual_present_time_ns;
|
||||
int64_t earliest_present_time_ns;
|
||||
int64_t present_margin_ns;
|
||||
int64_t now_ns;
|
||||
void
|
||||
call_u_pc_info(u_pacing_compositor *upc) const
|
||||
{
|
||||
|
@ -116,7 +116,7 @@ using SimulatedDisplayTimingQueue = std::priority_queue<SimulatedDisplayTimingDa
|
|||
|
||||
//! Process all simulated timing data in the queue that should be processed by now.
|
||||
static void
|
||||
processDisplayTimingQueue(SimulatedDisplayTimingQueue &display_timing_queue, uint64_t now_ns, u_pacing_compositor *upc)
|
||||
processDisplayTimingQueue(SimulatedDisplayTimingQueue &display_timing_queue, int64_t now_ns, u_pacing_compositor *upc)
|
||||
{
|
||||
while (!display_timing_queue.empty() && display_timing_queue.top().now_ns <= now_ns) {
|
||||
display_timing_queue.top().call_u_pc_info(upc);
|
||||
|
@ -124,8 +124,8 @@ processDisplayTimingQueue(SimulatedDisplayTimingQueue &display_timing_queue, uin
|
|||
}
|
||||
}
|
||||
//! Process all remaining simulated timing data in the queue and return the timestamp of the last one.
|
||||
static uint64_t
|
||||
drainDisplayTimingQueue(SimulatedDisplayTimingQueue &display_timing_queue, uint64_t now_ns, u_pacing_compositor *upc)
|
||||
static int64_t
|
||||
drainDisplayTimingQueue(SimulatedDisplayTimingQueue &display_timing_queue, int64_t now_ns, u_pacing_compositor *upc)
|
||||
{
|
||||
while (!display_timing_queue.empty()) {
|
||||
now_ns = display_timing_queue.top().now_ns;
|
||||
|
@ -139,8 +139,8 @@ static void
|
|||
doFrame(SimulatedDisplayTimingQueue &display_timing_queue,
|
||||
u_pacing_compositor *upc,
|
||||
MockClock &clock,
|
||||
uint64_t wake_time_ns,
|
||||
uint64_t desired_present_time_ns,
|
||||
int64_t wake_time_ns,
|
||||
int64_t desired_present_time_ns,
|
||||
int64_t frame_id,
|
||||
unanoseconds wake_delay,
|
||||
unanoseconds begin_delay,
|
||||
|
|
|
@ -8,97 +8,14 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#include <sstream>
|
||||
#include <functional>
|
||||
#include <iomanip>
|
||||
|
||||
using unanoseconds = std::chrono::duration<uint64_t, std::nano>;
|
||||
|
||||
|
||||
template <typename T>
|
||||
static inline std::string
|
||||
stringifyNanos(std::chrono::duration<T, std::nano> value)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
std::ostringstream oss;
|
||||
auto sec = duration_cast<duration<T>>(value);
|
||||
if (duration<T, std::nano>(sec) == value) {
|
||||
oss << sec.count() << "s";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
auto millis = duration_cast<duration<T, std::milli>>(value);
|
||||
if (duration<T, std::nano>(millis) == value) {
|
||||
oss << millis.count() << "ms";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
auto micros = duration_cast<duration<T, std::micro>>(value);
|
||||
if (duration<T, std::nano>(micros) == value) {
|
||||
oss << micros.count() << "us";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
oss << value.count() << "ns";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
static inline std::string
|
||||
stringifyTimePoint(std::chrono::steady_clock::time_point tp)
|
||||
{
|
||||
auto dur = tp.time_since_epoch();
|
||||
auto hr = std::chrono::duration_cast<std::chrono::hours>(dur);
|
||||
dur -= hr;
|
||||
auto sec = std::chrono::duration_cast<std::chrono::seconds>(dur);
|
||||
dur -= sec;
|
||||
std::ostringstream oss;
|
||||
if (hr.count() > 0) {
|
||||
oss << hr.count() << ":";
|
||||
}
|
||||
oss << sec.count() << ".";
|
||||
using three_commas =
|
||||
std::ratio_multiply<std::ratio<1, 1000>, std::ratio_multiply<std::ratio<1, 1000>, std::ratio<1, 1000>>>;
|
||||
static_assert(std::ratio_equal<three_commas, std::nano>::value);
|
||||
// 9 because of the preceding static assert: there's no compile-time rational log10? :-O
|
||||
oss << std::setfill('0') << std::setw(9);
|
||||
oss << dur.count();
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
namespace Catch {
|
||||
template <> struct StringMaker<unanoseconds>
|
||||
{
|
||||
static std::string
|
||||
convert(unanoseconds const &value)
|
||||
{
|
||||
return stringifyNanos(value);
|
||||
}
|
||||
};
|
||||
template <> struct StringMaker<std::chrono::nanoseconds>
|
||||
{
|
||||
static std::string
|
||||
convert(std::chrono::nanoseconds const &value)
|
||||
{
|
||||
return stringifyNanos(value);
|
||||
}
|
||||
};
|
||||
template <> struct StringMaker<std::chrono::steady_clock::time_point>
|
||||
{
|
||||
static std::string
|
||||
convert(std::chrono::steady_clock::time_point const &value)
|
||||
{
|
||||
return stringifyTimePoint(value);
|
||||
}
|
||||
};
|
||||
} // namespace Catch
|
||||
|
||||
using unanoseconds = std::chrono::duration<int64_t, std::nano>;
|
||||
|
||||
class MockClock
|
||||
{
|
||||
public:
|
||||
uint64_t
|
||||
int64_t
|
||||
now() const noexcept
|
||||
{
|
||||
return std::chrono::duration_cast<unanoseconds>(now_.time_since_epoch()).count();
|
||||
|
@ -117,7 +34,7 @@ public:
|
|||
}
|
||||
|
||||
void
|
||||
advance_to(uint64_t timestamp_ns)
|
||||
advance_to(int64_t timestamp_ns)
|
||||
{
|
||||
CHECK(now() <= timestamp_ns);
|
||||
now_ = std::chrono::steady_clock::time_point(
|
||||
|
|
Loading…
Reference in a new issue