Compositor的主要结构体
1、comp_compositor
/*!
* Main compositor struct tying everything in the compositor together.
*
* @ingroup comp_main
* @implements xrt_compositor_native
*/
struct comp_compositor
{
struct comp_base base;
//! Renderer helper.渲染帮助类
struct comp_renderer *r;
//! The target we are displaying to.渲染目标
struct comp_target *target;
//! The device we are displaying to.渲染设备
struct xrt_device *xdev;
//! The settings.设置相关
struct comp_settings settings;
//! Vulkan shaders that the compositor uses.
struct comp_shaders shaders;
//! Timestamp of last-rendered (immersive) frame.最后一帧的渲染时间
int64_t last_frame_time_ns;
//! State for generating the correct set of events.
enum comp_state state;
// Extents of one view, in pixels.扩展
VkExtent2D view_extents;
//! Are we mirroring any of the views to the debug gui? If so, turn off the fast path.
bool mirroring_to_debug_gui;
/*!begin_frame end_frame 独有的数据,用于计算应用程序需求的估计值
* @brief Data exclusive to the begin_frame/end_frame for computing an
* estimate of the app's needs.
*/
struct
{
int64_t last_begin;
int64_t last_end;
} app_profiling;
struct u_frame_times_widget compositor_frame_times;
struct
{
struct comp_frame waited;//等待帧
struct comp_frame rendering;//渲染帧
} frame;
struct
{
//! Temporarily disable ATW
bool atw_off;//ATW开关
} debug;
struct comp_resources nr;
};
2、comp_base
comp_compositor的子结构体
/*!
* A simple compositor base that handles a lot of things for you.
* 一个简单的合成器
* Things it handles for you:
* * App swapchains 应用交换链
* * App fences
* * Vulkan bundle (needed for swapchains and fences) Vulkan 捆绑包
* * Layer tracking, not @ref xrt_compositor::layer_commit
* * Wait function, not @ref xrt_compositor::predict_frame
*
* Functions it does not handle:
* * @ref xrt_compositor::begin_session 开始session
* * @ref xrt_compositor::end_session 结束session
* * @ref xrt_compositor::predict_frame 预测帧
* * @ref xrt_compositor::mark_frame 标记帧
* * @ref xrt_compositor::begin_frame 开始帧
* * @ref xrt_compositor::discard_frame 弃用帧
* * @ref xrt_compositor::layer_commit 提交layer
* * @ref xrt_compositor::poll_events 循环事件
* * @ref xrt_compositor::destroy 销毁
*
* @ingroup comp_util
* @see comp_base
*/
struct comp_base
{
//! Base native compositor. 以来底层合成器
struct xrt_compositor_native base;
//! Vulkan bundle of useful things, used by swapchain and fence.
//ulkan 包有用的东西,被交换链和栅栏使用
struct vk_bundle vk;
//! For default @ref xrt_compositor::wait_frame.
//Swapchain 垃圾收集器,swapchain 使用,子类需要调用
struct os_precise_sleeper sleeper;
//! Swapchain garbage collector, used by swapchain, child class needs to call.
// Swapchain 垃圾收集器,swapchain 使用,子类需要调用
struct comp_swapchain_gc cscgc;
//! We only need to track a single slot.
//我们只需要跟踪一个
struct comp_layer_slot slot;
};
3、xrt_compositor_native
/*!
* @interface xrt_compositor_native
*
* Main compositor server interface.
主合成器服务器接口
* 包含xrt_compositor
* @ingroup xrt_iface comp
* @extends xrt_compositor
*/
struct xrt_compositor_native
{
//! @public Base
struct xrt_compositor base;
};
4、xrt_compositor
/*!
* @interface xrt_compositor
*
* Common compositor client interface/base.
* compositor公共接口
合成器非常类似于`XrSession`,但没有任何输入功能,并且与`XrSession`具有相同的生命周期
* A compositor is very much analogous to a `XrSession` but without any of the
* input functionality, and does have the same life time as a `XrSession`.
*/
struct xrt_compositor
{
/*!
* Capabilities and recommended values information.
*/
struct xrt_compositor_info info;
/*!
* Create a swapchain with a set of images.
* 为一堆图像创建交换链
* The pointer pointed to by @p out_xsc has to either be NULL or a valid
* @ref xrt_swapchain pointer. If there is a valid @ref xrt_swapchain
* pointed by the pointed pointer it will have it reference decremented.
*/
xrt_result_t (*create_swapchain)(struct xrt_compositor *xc,
const struct xrt_swapchain_create_info *info,
struct xrt_swapchain **out_xsc);
/*!
* Create a swapchain from a set of native images.
*
* The pointer pointed to by @p out_xsc has to either be NULL or a valid
* @ref xrt_swapchain pointer. If there is a valid @ref xrt_swapchain
* pointed by the pointed pointer it will have it reference decremented.
*/
xrt_result_t (*import_swapchain)(struct xrt_compositor *xc,
const struct xrt_swapchain_create_info *info,
struct xrt_image_native *native_images,
uint32_t image_count,
struct xrt_swapchain **out_xsc);
/*!
* Create a compositor fence from a native sync handle.
*/
xrt_result_t (*import_fence)(struct xrt_compositor *xc,
xrt_graphics_sync_handle_t handle,
struct xrt_compositor_fence **out_xcf);
/*!
* Create a compositor semaphore, also returns a native handle.
*/
xrt_result_t (*create_semaphore)(struct xrt_compositor *xc,
xrt_graphics_sync_handle_t *out_handle,
struct xrt_compositor_semaphore **out_xcsem);
/*!
* Poll events from this compositor.
*
* This function is very much WIP.
*/
xrt_result_t (*poll_events)(struct xrt_compositor *xc, union xrt_compositor_event *out_xce);
/*!
* See xrBeginSession.
*/
xrt_result_t (*begin_session)(struct xrt_compositor *xc, enum xrt_view_type view_type);
/*!
* See xrEndSession, unlike the OpenXR one the state tracker is
* responsible to call discard frame before calling this function. See
* discard_frame.
*/
xrt_result_t (*end_session)(struct xrt_compositor *xc);
/*!
* This function and @ref mark_frame function calls are a alternative to
* @ref wait_frame.
*
* The only requirement on the compositor for the @p frame_id
* is that it is a positive number and larger then the last returned
* frame_id.
*调用predict_frame 之后只能等mark_frame之后才能再次调用
* After a call to predict_frame, the state tracker is not allowed to
* call this function until after a call to @ref mark_frame (with point
* @ref XRT_COMPOSITOR_FRAME_POINT_WOKE), followed by either
* @ref begin_frame or @ref discard_frame.
*
* @param[in] xc The compositor
* @param[out] out_frame_id Frame id
* @param[out] out_wake_time_ns When we want the client to be awoken to begin rendering.
* @param[out] out_predicted_gpu_time_ns When we expect the client to finish the GPU work. If not
* computed/available, set to 0.
* @param[out] out_predicted_display_time_ns When the pixels turns into photons.
* @param[out] out_predicted_display_period_ns The period for the frames.
*/
xrt_result_t (*predict_frame)(struct xrt_compositor *xc,
int64_t *out_frame_id,
uint64_t *out_wake_time_ns,
uint64_t *out_predicted_gpu_time_ns,
uint64_t *out_predicted_display_time_ns,
uint64_t *out_predicted_display_period_ns);
/*!
* This function and @ref predict_frame function calls are a alternative to
* @ref wait_frame.
*
* If point is @ref XRT_COMPOSITOR_FRAME_POINT_WOKE it is to mark that the
* client woke up from waiting on a frame.
*
* @param[in] xc The compositor
* @param[in] frame_id Frame id
* @param[in] point What type of frame point to mark.
* @param[in] when_ns When this point happened.
*/
xrt_result_t (*mark_frame)(struct xrt_compositor *xc,
int64_t frame_id,
enum xrt_compositor_frame_point point,
uint64_t when_ns);
/*!
* See xrWaitFrame.
*
* This function has the same semantics as calling @ref predict_frame,
* sleeping, and then calling @ref mark_frame with a point of
* @ref XRT_COMPOSITOR_FRAME_POINT_WOKE.
*
* The only requirement on the compositor for the @p frame_id
* is that it is a positive number and larger then the last returned
* @p frame_id.
*
* After a call to wait_frame, the state tracker is not allowed to call
* this function until after a call to either @ref begin_frame or
* @ref discard_frame.
*
* If the caller can do its own blocking, use the pair of functions
* xrt_compositor::predict_frame and xrt_compositor::mark_frame instead
* of this single blocking function.
*/
xrt_result_t (*wait_frame)(struct xrt_compositor *xc,
int64_t *out_frame_id,
uint64_t *out_predicted_display_time,
uint64_t *out_predicted_display_period);
/*!
* See xrBeginFrame.
*
* Must have made a call to either @ref predict_frame or @ref wait_frame
* before calling this function. After this function is called you must
* call layer_commit.
*
* @param[in] xc The compositor
* @param[in] frame_id Frame id
*/
xrt_result_t (*begin_frame)(struct xrt_compositor *xc, int64_t frame_id);
/*!
* @brief Explicitly discard a frame.
*
* This isn't in the OpenXR API but is explicit in the XRT interfaces.
*
* Two calls to xrBeginFrame without intervening xrEndFrame will cause
* the state tracker to call:
*
* ```c
* // first xrBeginFrame
* xrt_comp_begin_frame(xc, frame_id);
* // second xrBeginFrame
* xrt_comp_discard_frame(xc, frame_id);
* xrt_comp_begin_frame(xc, frame_id);
* ```
*/
xrt_result_t (*discard_frame)(struct xrt_compositor *xc, int64_t frame_id);
/*!
* @brief Begins