[client] wayland: publish stable presentation cadence

This commit is contained in:
Geoffrey McRae
2026-08-06 17:11:03 +10:00
parent 988675e53a
commit 1b78384da3
4 changed files with 26 additions and 5 deletions

View File

@@ -325,6 +325,7 @@ static void outputDoneHandler(void * opaque, struct wl_output * output)
{ {
struct WaylandOutput * node = opaque; struct WaylandOutput * node = opaque;
outputUpdateScale(node); outputUpdateScale(node);
waylandOutputUpdateFramePeriod();
} }
static void outputScaleHandler(void * opaque, struct wl_output * output, int32_t scale) static void outputScaleHandler(void * opaque, struct wl_output * output, int32_t scale)
@@ -401,6 +402,7 @@ void waylandOutputFree(void)
wl_list_remove(&node->link); wl_list_remove(&node->link);
free(node); free(node);
} }
atomic_store_explicit(&wlWm.nominalPeriod, 0, memory_order_release);
} }
void waylandOutputBind(uint32_t name, uint32_t version) void waylandOutputBind(uint32_t name, uint32_t version)
@@ -470,6 +472,7 @@ void waylandOutputTryUnbind(uint32_t name)
free(node); free(node);
waylandWindowUpdateScale(); waylandWindowUpdateScale();
waylandOutputUpdateHDRWhiteLevel(); waylandOutputUpdateHDRWhiteLevel();
waylandOutputUpdateFramePeriod();
break; break;
} }
} }
@@ -485,7 +488,7 @@ struct WaylandScale waylandOutputGetScale(struct wl_output * output)
return waylandScaleFromInt(0); return waylandScaleFromInt(0);
} }
bool waylandOutputGetFramePeriod(uint64_t * period) void waylandOutputUpdateFramePeriod(void)
{ {
uint64_t fastest = 0; uint64_t fastest = 0;
struct SurfaceOutput * surfaceOutput; struct SurfaceOutput * surfaceOutput;
@@ -502,6 +505,15 @@ bool waylandOutputGetFramePeriod(uint64_t * period)
fastest = candidate; fastest = candidate;
} }
atomic_store_explicit(
&wlWm.nominalPeriod, fastest, memory_order_release);
}
bool waylandOutputGetFramePeriod(uint64_t * period)
{
const uint64_t fastest = atomic_load_explicit(
&wlWm.nominalPeriod, memory_order_acquire);
if (!fastest) if (!fastest)
return false; return false;

View File

@@ -39,6 +39,8 @@ static void presentationClockId(void * data,
struct wp_presentation * presentation, uint32_t clkId) struct wp_presentation * presentation, uint32_t clkId)
{ {
wlWm.clkId = clkId; wlWm.clkId = clkId;
atomic_store_explicit(
&wlWm.presentationClockValid, true, memory_order_release);
} }
static const struct wp_presentation_listener presentationListener = { static const struct wp_presentation_listener presentationListener = {
@@ -56,8 +58,6 @@ static void presentationFeedbackPresented(void * opaque,
uint32_t tvNsec, uint32_t refresh, uint32_t seqHi, uint32_t seqLo, uint32_t flags) uint32_t tvNsec, uint32_t refresh, uint32_t seqHi, uint32_t seqLo, uint32_t flags)
{ {
struct FrameData * data = opaque; struct FrameData * data = opaque;
if (refresh)
atomic_store(&wlWm.presentationPeriod, refresh);
struct timespec present = { struct timespec present = {
.tv_sec = (uint64_t) tvSecHi << 32 | tvSecLo, .tv_sec = (uint64_t) tvSecHi << 32 | tvSecLo,
.tv_nsec = tvNsec, .tv_nsec = tvNsec,
@@ -96,6 +96,8 @@ bool waylandPresentationInit(void)
{ {
if (wlWm.presentation) if (wlWm.presentation)
{ {
atomic_store_explicit(
&wlWm.presentationClockValid, false, memory_order_release);
wlWm.photonTimings = ringbuffer_new(256, sizeof(float)); wlWm.photonTimings = ringbuffer_new(256, sizeof(float));
wlWm.photonGraph = app_registerGraph("PHOTON", wlWm.photonTimings, wlWm.photonGraph = app_registerGraph("PHOTON", wlWm.photonTimings,
0.0f, 30.0f, NULL); 0.0f, 30.0f, NULL);
@@ -110,6 +112,8 @@ void waylandPresentationFree(void)
if (!wlWm.presentation) if (!wlWm.presentation)
return; return;
atomic_store_explicit(
&wlWm.presentationClockValid, false, memory_order_release);
wp_presentation_destroy(wlWm.presentation); wp_presentation_destroy(wlWm.presentation);
app_unregisterGraph(wlWm.photonGraph); app_unregisterGraph(wlWm.photonGraph);
ringbuffer_free(&wlWm.photonTimings); ringbuffer_free(&wlWm.photonTimings);
@@ -117,7 +121,8 @@ void waylandPresentationFree(void)
void waylandPresentationFrame(void) void waylandPresentationFrame(void)
{ {
if (!wlWm.presentation) if (!wlWm.presentation || !atomic_load_explicit(
&wlWm.presentationClockValid, memory_order_acquire))
return; return;
struct FrameData * data = malloc(sizeof(*data)); struct FrameData * data = malloc(sizeof(*data));

View File

@@ -161,7 +161,8 @@ struct WaylandDSState
struct wp_presentation * presentation; struct wp_presentation * presentation;
clockid_t clkId; clockid_t clkId;
_Atomic(uint64_t) presentationPeriod; _Atomic(bool) presentationClockValid;
_Atomic(uint64_t) nominalPeriod;
RingBuffer photonTimings; RingBuffer photonTimings;
GraphHandle photonGraph; GraphHandle photonGraph;
@@ -397,6 +398,7 @@ void waylandOutputBind(uint32_t name, uint32_t version);
void waylandOutputTryUnbind(uint32_t name); void waylandOutputTryUnbind(uint32_t name);
struct WaylandScale waylandOutputGetScale(struct wl_output * output); struct WaylandScale waylandOutputGetScale(struct wl_output * output);
bool waylandOutputGetFramePeriod(uint64_t * period); bool waylandOutputGetFramePeriod(uint64_t * period);
void waylandOutputUpdateFramePeriod(void);
void waylandOutputColorMgmtInit(struct WaylandOutput * output); void waylandOutputColorMgmtInit(struct WaylandOutput * output);
void waylandOutputColorMgmtInitAll(void); void waylandOutputColorMgmtInitAll(void);
void waylandOutputUpdateHDRWhiteLevel(void); void waylandOutputUpdateHDRWhiteLevel(void);

View File

@@ -92,6 +92,7 @@ static void wlSurfaceEnterHandler(void * data, struct wl_surface * surface, stru
wl_list_insert(&wlWm.surfaceOutputs, &node->link); wl_list_insert(&wlWm.surfaceOutputs, &node->link);
waylandWindowUpdateScale(); waylandWindowUpdateScale();
waylandOutputUpdateHDRWhiteLevel(); waylandOutputUpdateHDRWhiteLevel();
waylandOutputUpdateFramePeriod();
} }
static void wlSurfaceLeaveHandler(void * data, struct wl_surface * surface, struct wl_output * output) static void wlSurfaceLeaveHandler(void * data, struct wl_surface * surface, struct wl_output * output)
@@ -106,6 +107,7 @@ static void wlSurfaceLeaveHandler(void * data, struct wl_surface * surface, stru
} }
waylandWindowUpdateScale(); waylandWindowUpdateScale();
waylandOutputUpdateHDRWhiteLevel(); waylandOutputUpdateHDRWhiteLevel();
waylandOutputUpdateFramePeriod();
} }
static const struct wl_surface_listener wlSurfaceListener = { static const struct wl_surface_listener wlSurfaceListener = {