u/pacing: Introduce a app pacing factory

This commit is contained in:
Jakob Bornecrantz 2022-06-27 18:30:37 +01:00
parent 6e2644dea7
commit 2cbad30823
8 changed files with 134 additions and 14 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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);
}