From 2cbad30823409b9402c6bfd6b9750261b1db68bd Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 27 Jun 2022 18:30:37 +0100 Subject: [PATCH] u/pacing: Introduce a app pacing factory --- src/xrt/auxiliary/util/u_pacing.h | 67 ++++++++++++++++++- src/xrt/auxiliary/util/u_pacing_app.c | 49 +++++++++++--- src/xrt/compositor/main/comp_compositor.c | 8 ++- .../compositor/multi/comp_multi_compositor.c | 2 +- .../compositor/multi/comp_multi_interface.h | 8 +++ src/xrt/compositor/multi/comp_multi_private.h | 3 + src/xrt/compositor/multi/comp_multi_system.c | 4 ++ src/xrt/compositor/null/null_compositor.c | 7 +- 8 files changed, 134 insertions(+), 14 deletions(-) diff --git a/src/xrt/auxiliary/util/u_pacing.h b/src/xrt/auxiliary/util/u_pacing.h index d5e53f85e..7ab08d3e2 100644 --- a/src/xrt/auxiliary/util/u_pacing.h +++ b/src/xrt/auxiliary/util/u_pacing.h @@ -507,6 +507,69 @@ u_pa_destroy(struct u_pacing_app **upa_ptr) *upa_ptr = NULL; } + +/* + * + * App pacing factory. + * + */ + +/*! + * Small helper that creates a app pacers, allows timing information to be + * collected and controlled to a central place. + */ +struct u_pacing_app_factory +{ + /*! + * Create a @ref u_pacing_app. + * + * @param upaf App pacing factory. + * @param[out] out_upa Created app pacer. + */ + xrt_result_t (*create)(struct u_pacing_app_factory *upaf, struct u_pacing_app **out_upa); + + /*! + * Destroy this u_pacing_app_factory. + */ + void (*destroy)(struct u_pacing_app_factory *upaf); +}; + +/*! + * @copydoc u_pacing_app_factory::create + * + * Helper for calling through the function pointer. + * + * @public @memberof u_pacing_app_factory + * @ingroup aux_pacing + */ +static inline void +u_paf_create(struct u_pacing_app_factory *upaf, struct u_pacing_app **out_upa) +{ + upaf->create(upaf, out_upa); +} + +/*! + * @copydoc u_pacing_app_factory::destroy + * + * Helper for calling through the function pointer: does a null check and sets + * upa_ptr to null if freed. + * + * @public @memberof u_pacing_app_factory + * @ingroup aux_pacing + */ +static inline void +u_paf_destroy(struct u_pacing_app_factory **upaf_ptr) +{ + struct u_pacing_app_factory *upaf = *upaf_ptr; + if (upaf == NULL) { + return; + } + + upaf->destroy(upaf); + *upaf_ptr = NULL; +} + + /* * * Configuration struct @@ -585,13 +648,13 @@ xrt_result_t u_pc_fake_create(uint64_t estimated_frame_period_ns, uint64_t now_ns, struct u_pacing_compositor **out_upc); /*! - * Creates a new application pacing helper. + * Creates a new application pacing factory helper. * * @ingroup aux_pacing * @see u_pacing_app */ xrt_result_t -u_pa_create(struct u_pacing_app **out_upa); +u_pa_factory_create(struct u_pacing_app_factory **out_upaf); #ifdef __cplusplus diff --git a/src/xrt/auxiliary/util/u_pacing_app.c b/src/xrt/auxiliary/util/u_pacing_app.c index 8ce2490b4..af4b0fdba 100644 --- a/src/xrt/auxiliary/util/u_pacing_app.c +++ b/src/xrt/auxiliary/util/u_pacing_app.c @@ -448,15 +448,8 @@ pa_destroy(struct u_pacing_app *upa) free(upa); } - -/* - * - * 'Exported' functions. - * - */ - -xrt_result_t -u_pa_create(struct u_pacing_app **out_upa) +static xrt_result_t +pa_create(struct u_pacing_app **out_upa) { struct pacing_app *pa = U_TYPED_CALLOC(struct pacing_app); pa->base.predict = pa_predict; @@ -479,3 +472,41 @@ u_pa_create(struct u_pacing_app **out_upa) return XRT_SUCCESS; } + + +/* + * + * Factory functions. + * + */ + +static xrt_result_t +paf_create(struct u_pacing_app_factory *upaf, struct u_pacing_app **out_upa) +{ + return pa_create(out_upa); +} + +static void +paf_destroy(struct u_pacing_app_factory *upaf) +{ + free(upaf); +} + + +/* + * + * 'Exported' functions. + * + */ + +xrt_result_t +u_pa_factory_create(struct u_pacing_app_factory **out_upaf) +{ + struct u_pacing_app_factory *upaf = U_TYPED_CALLOC(struct u_pacing_app_factory); + upaf->create = paf_create; + upaf->destroy = paf_destroy; + + *out_upaf = upaf; + + return XRT_SUCCESS; +} diff --git a/src/xrt/compositor/main/comp_compositor.c b/src/xrt/compositor/main/comp_compositor.c index e7386ab3b..95b094397 100644 --- a/src/xrt/compositor/main/comp_compositor.c +++ b/src/xrt/compositor/main/comp_compositor.c @@ -51,6 +51,7 @@ #include "util/u_misc.h" #include "util/u_time.h" #include "util/u_debug.h" +#include "util/u_pacing.h" #include "util/u_handles.h" #include "util/u_trace_marker.h" #include "util/u_distortion_mesh.h" @@ -1268,5 +1269,10 @@ xrt_gfx_provider_create_system(struct xrt_device *xdev, struct xrt_system_compos c->state = COMP_STATE_READY; - return comp_multi_create_system_compositor(&c->base.base, sys_info, out_xsysc); + // Standard app pacer. + struct u_pacing_app_factory *upaf = NULL; + xrt_result_t xret = u_pa_factory_create(&upaf); + assert(xret == XRT_SUCCESS && upaf != NULL); + + return comp_multi_create_system_compositor(&c->base.base, upaf, sys_info, out_xsysc); } diff --git a/src/xrt/compositor/multi/comp_multi_compositor.c b/src/xrt/compositor/multi/comp_multi_compositor.c index 4b4cbab81..41ad0dd19 100644 --- a/src/xrt/compositor/multi/comp_multi_compositor.c +++ b/src/xrt/compositor/multi/comp_multi_compositor.c @@ -925,7 +925,7 @@ multi_compositor_create(struct multi_system_compositor *msc, os_precise_sleeper_init(&mc->sleeper); // This is safe to do without a lock since we are not on the list yet. - u_pa_create(&mc->upa); + u_paf_create(msc->upaf, &mc->upa); os_mutex_lock(&msc->list_and_timing_lock); diff --git a/src/xrt/compositor/multi/comp_multi_interface.h b/src/xrt/compositor/multi/comp_multi_interface.h index 55b24edf3..f5cffa6b5 100644 --- a/src/xrt/compositor/multi/comp_multi_interface.h +++ b/src/xrt/compositor/multi/comp_multi_interface.h @@ -16,9 +16,17 @@ extern "C" { #endif +struct u_pacing_app_factory; + +/*! + * Create a system compositor that can handle multiple clients and that drives + * a single native compositor. Both the native compositor and the pacing factory + * is owned by the multi compositor and destroyed by it. + */ xrt_result_t comp_multi_create_system_compositor(struct xrt_compositor_native *xcn, + struct u_pacing_app_factory *upaf, const struct xrt_system_compositor_info *xsci, struct xrt_system_compositor **out_xsysc); diff --git a/src/xrt/compositor/multi/comp_multi_private.h b/src/xrt/compositor/multi/comp_multi_private.h index 0ec145d15..3779ed4f3 100644 --- a/src/xrt/compositor/multi/comp_multi_private.h +++ b/src/xrt/compositor/multi/comp_multi_private.h @@ -240,6 +240,9 @@ struct multi_system_compositor //! Real native compositor. struct xrt_compositor_native *xcn; + //! App pacer factory. + struct u_pacing_app_factory *upaf; + //! Render loop thread. struct os_thread_helper oth; diff --git a/src/xrt/compositor/multi/comp_multi_system.c b/src/xrt/compositor/multi/comp_multi_system.c index 30d876ff2..371d28e11 100644 --- a/src/xrt/compositor/multi/comp_multi_system.c +++ b/src/xrt/compositor/multi/comp_multi_system.c @@ -508,6 +508,8 @@ system_compositor_destroy(struct xrt_system_compositor *xsc) // Destroy the render thread first, destroy also stops the thread. os_thread_helper_destroy(&msc->oth); + u_paf_destroy(&msc->upaf); + xrt_comp_native_destroy(&msc->xcn); os_mutex_destroy(&msc->list_and_timing_lock); @@ -524,6 +526,7 @@ system_compositor_destroy(struct xrt_system_compositor *xsc) xrt_result_t comp_multi_create_system_compositor(struct xrt_compositor_native *xcn, + struct u_pacing_app_factory *upaf, const struct xrt_system_compositor_info *xsci, struct xrt_system_compositor **out_xsysc) { @@ -535,6 +538,7 @@ comp_multi_create_system_compositor(struct xrt_compositor_native *xcn, msc->xmcc.set_main_app_visibility = system_compositor_set_main_app_visibility; msc->base.xmcc = &msc->xmcc; msc->base.info = *xsci; + msc->upaf = upaf; msc->xcn = xcn; os_mutex_init(&msc->list_and_timing_lock); diff --git a/src/xrt/compositor/null/null_compositor.c b/src/xrt/compositor/null/null_compositor.c index 1f30023bd..d65a97479 100644 --- a/src/xrt/compositor/null/null_compositor.c +++ b/src/xrt/compositor/null/null_compositor.c @@ -578,5 +578,10 @@ null_compositor_create_system(struct xrt_device *xdev, struct xrt_system_composi NULL_DEBUG(c, "Done %p", (void *)c); - return comp_multi_create_system_compositor(&c->base.base, &c->sys_info, out_xsysc); + // Standard app pacer. + struct u_pacing_app_factory *upaf = NULL; + xrt_result_t xret = u_pa_factory_create(&upaf); + assert(xret == XRT_SUCCESS && upaf != NULL); + + return comp_multi_create_system_compositor(&c->base.base, upaf, &c->sys_info, out_xsysc); }