u/pacing: Work around issues with frame reuse

The code creates a frame with the timing information, and keeps track of the
times the applications does various things during the frame loop. Like
starting to render and finished rendering and so on. It keeps track of that
frame until it has determined that the application or the system compositor
will never do anything thing with that frame.

Now the allocation side of thing is very simple, just a long array of
FRAME_COUNT size that is reused with frame_id % FRAME_COUNT. So if the
application or the compositor keeps a frame along for too long it will try to
reuse that frame. The code has asserts to catch this. Making FRAME_COUNT makes
that re-use more unlikely.
This commit is contained in:
Jakob Bornecrantz 2022-11-02 00:22:16 +00:00
parent a5f10e7aa2
commit 7b1c18255a

View file

@ -1,4 +1,4 @@
// Copyright 2020-2021, Collabora, Ltd.
// Copyright 2020-2022, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
@ -28,6 +28,12 @@ DEBUG_GET_ONCE_LOG_OPTION(log_level, "U_PACING_APP_LOG", U_LOGGING_WARN)
#define UPA_LOG_W(...) U_LOG_IFL_W(debug_get_log_option_log_level(), __VA_ARGS__)
#define UPA_LOG_E(...) U_LOG_IFL_E(debug_get_log_option_log_level(), __VA_ARGS__)
/*!
* Define to validate latched and retired call. Currently disabled due to
* simplistic frame allocation code, enable once improved.
*/
#undef VALIDATE_LATCHED_AND_RETIRED
/*
*
@ -451,6 +457,13 @@ pa_mark_gpu_done(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns)
// Write out tracing data.
do_tracing(pa, f);
#ifndef VALIDATE_LATCHED_AND_RETIRED
// Reset the frame.
U_ZERO(f);
f->state = U_PA_READY;
f->frame_id = -1;
#endif
}
static void
@ -458,7 +471,14 @@ pa_latched(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns, int64_t
{
struct pacing_app *pa = pacing_app(upa);
#ifdef VALIDATE_LATCHED_AND_RETIRED
size_t index = GET_INDEX_FROM_ID(pa, frame_id);
struct u_pa_frame *f = &pa->frames[index];
assert(f->frame_id == frame_id);
assert(f->state == U_RT_GPU_DONE);
#else
(void)pa;
#endif
}
static void
@ -466,14 +486,19 @@ pa_retired(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns)
{
struct pacing_app *pa = pacing_app(upa);
#ifdef VALIDATE_LATCHED_AND_RETIRED
size_t index = GET_INDEX_FROM_ID(pa, frame_id);
struct u_pa_frame *f = &pa->frames[index];
assert(f->frame_id == frame_id);
assert(f->state == U_RT_GPU_DONE || f->state == U_RT_DELIVERED);
// Reset the frame.
U_ZERO(f);
f->state = U_PA_READY;
f->frame_id = -1;
#else
(void)pa;
#endif
}
static void