mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-24 07:31:48 +00:00
146 lines
4 KiB
C
146 lines
4 KiB
C
// Copyright 2020, Collabora, Ltd.
|
|
// SPDX-License-Identifier: BSL-1.0
|
|
/*!
|
|
* @file
|
|
* @brief Shared frame timing code.
|
|
* @author Jakob Bornecrantz <jakob@collabora.com>
|
|
* @ingroup aux_util
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "xrt/xrt_compiler.h"
|
|
#include "os/os_time.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
|
|
enum u_rt_state
|
|
{
|
|
U_RT_READY,
|
|
U_RT_WAIT_LEFT,
|
|
U_RT_PREDICTED,
|
|
U_RT_BEGUN,
|
|
};
|
|
|
|
struct u_rt_frame
|
|
{
|
|
uint64_t predicted;
|
|
uint64_t wait_woke;
|
|
uint64_t begin;
|
|
uint64_t end_frame;
|
|
int64_t frame_id;
|
|
enum u_rt_state state;
|
|
};
|
|
|
|
/*!
|
|
* This render timing helper is designed to schedule the rendering time of
|
|
* clients that submit frames to a compositor, which runs its own render loop
|
|
* that picks latest completed frames for that client.
|
|
*/
|
|
struct u_rt_helper
|
|
{
|
|
struct u_rt_frame frames[2];
|
|
uint32_t current_frame;
|
|
uint32_t next_frame;
|
|
|
|
int64_t frame_counter;
|
|
|
|
struct
|
|
{
|
|
//! The last display time that the thing driving this helper got.
|
|
uint64_t predicted_display_time_ns;
|
|
//! The last display period the hardware is running at.
|
|
uint64_t predicted_display_period_ns;
|
|
//! The extra time needed by the thing driving this helper.
|
|
uint64_t extra_ns;
|
|
} last_input;
|
|
|
|
uint64_t last_returned_ns;
|
|
};
|
|
|
|
void
|
|
u_rt_helper_init(struct u_rt_helper *urth);
|
|
|
|
/*!
|
|
* This function gets the client part of the render timing helper ready to be
|
|
* used. If you use init you will also clear all of the timing information.
|
|
*
|
|
* Call this when resetting a client.
|
|
*/
|
|
void
|
|
u_rt_helper_client_clear(struct u_rt_helper *urth);
|
|
|
|
/*!
|
|
* Predict when the client's next rendered frame will be presented, also when
|
|
* the client should be woken up from sleeping, its display period and the
|
|
* minimum display period that the client might have.
|
|
*
|
|
* This is called from `xrWaitFrame`, but it does not do any waiting, the caller
|
|
* should wait till `out_wake_up_time`.
|
|
*/
|
|
void
|
|
u_rt_helper_predict(struct u_rt_helper *urth,
|
|
int64_t *out_frame_id,
|
|
uint64_t *out_predicted_display_time,
|
|
uint64_t *out_wake_up_time,
|
|
uint64_t *out_predicted_display_period,
|
|
uint64_t *out_min_display_period);
|
|
|
|
/*!
|
|
* Log when the client woke up after sleeping for the time returned in
|
|
* @ref u_rt_helper_predict. This happens inside of `xrWaitFrame`.
|
|
*/
|
|
void
|
|
u_rt_helper_mark_wait_woke(struct u_rt_helper *urth, int64_t frame_id);
|
|
|
|
/*!
|
|
* The client has started rendering work, see `xrBeginFrame`.
|
|
*/
|
|
void
|
|
u_rt_helper_mark_begin(struct u_rt_helper *urth, int64_t frame_id);
|
|
|
|
/*!
|
|
* When a frame has been discared.
|
|
*/
|
|
void
|
|
u_rt_helper_mark_discarded(struct u_rt_helper *urth, int64_t frame_id);
|
|
|
|
/*!
|
|
* A frame has been delivered from the client, see `xrEndFrame`. The GPU might
|
|
* still be rendering the work.
|
|
*/
|
|
void
|
|
u_rt_helper_mark_delivered(struct u_rt_helper *urth, int64_t frame_id);
|
|
|
|
/*!
|
|
* Add a new sample point from the main render loop.
|
|
*
|
|
* This is called in the main renderer loop that tightly submits frames to the
|
|
* real compositor for displaying. This is only used to inform the render helper
|
|
* when the frame will be shown, not any timing information about the client.
|
|
*
|
|
* When this is called doesn't matter that much, as the render timing will need
|
|
* to be able to predict one or more frames into the future anyways. But
|
|
* preferably as soon as the main loop wakes up from wait frame.
|
|
*
|
|
* @param urth Self pointer
|
|
* @param predicted_display_time_ns Predicted display time for this sample.
|
|
* @param predicted_display_period_ns Predicted display period for this sample.
|
|
* @param extra_ns Time between display and when this sample
|
|
* was created, that is when the main loop
|
|
* was woken up by the main compositor.
|
|
*/
|
|
void
|
|
u_rt_helper_new_sample(struct u_rt_helper *urth,
|
|
uint64_t predicted_display_time_ns,
|
|
uint64_t predicted_display_period_ns,
|
|
uint64_t extra_ns);
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|