Skip to content

Commit

Permalink
(shmif) merge compatible stepframes, preroll fdfix
Browse files Browse the repository at this point in the history
With the clockreq changes from b3364d the chance for a buildup on
a stalled client is substantially higher. While realtime performance
is to be asked of someone explicitly asking for vblank feedback, it
is not always in their control. To help congestion then, add stepframe
to the list of valid candidates.

This also fixes a subtle thing to take note of and monitor for. Normally
fd- transfer events aren't necessary during preroll, with a notable
exception being DEVICEHINT for specifically routing a GPU, though that
has not yet been used. While re-using shmif for other purposes, it was
discovered that the first descriptor transfer during a preroll could be
dropped, never to find the descriptor. Whether this is posix-madness
that will come back to bite us or not is to be seen, but change the
behaviour to retry when an expected descriptor does not arrive - instead
of returning an event with a bad descriptor field.
  • Loading branch information
letoram committed Sep 16, 2023
1 parent 7c13a1b commit 1776236
Showing 1 changed file with 28 additions and 2 deletions.
30 changes: 28 additions & 2 deletions src/shmif/arcan_shmif_control.c
Expand Up @@ -558,6 +558,25 @@ static bool calc_dirty(
return true;
}

static bool scan_stepframe_event(
struct arcan_evctx*c, struct arcan_event* old, int id)
{
if (old->tgt.ioevs[1].iv != id)
return false;
uint8_t cur = *c->front;

/* conservative merge on STEPFRAME so far is results from VBLANK polling only */
while (cur != *c->back){
struct arcan_event* ev = &c->eventbuf[cur];
if (ev->category == EVENT_TARGET &&
ev->tgt.kind == TARGET_COMMAND_STEPFRAME &&
ev->tgt.ioevs[1].iv == id)
return true;
cur = (cur + 1) % c->eventbuf_sz;
}
return false;
}

static bool scan_disp_event(struct arcan_evctx* c, struct arcan_event* old)
{
uint8_t cur = *c->front;
Expand Down Expand Up @@ -801,8 +820,10 @@ static int process_events(struct arcan_shmif_cont* c,
*/
checkfd:
do {
if (-1 == priv->pev.fd)
errno = 0;
if (-1 == priv->pev.fd){
priv->pev.fd = arcan_fetchhandle(c->epipe, blocking);
}

if (priv->pev.gotev){
if (blocking){
Expand All @@ -820,7 +841,7 @@ static int process_events(struct arcan_shmif_cont* c,
else if (blocking){
debug_print(STATUS, c, "failure on blocking fd-wait: %s, %s",
strerror(errno), arcan_shmif_eventstr(&priv->pev.ev, NULL, 0));
if (errno == EAGAIN)
if (!errno || errno == EAGAIN)
continue;
}

Expand Down Expand Up @@ -865,6 +886,11 @@ static int process_events(struct arcan_shmif_cont* c,
goto reset;
break;

case TARGET_COMMAND_STEPFRAME:
if (scan_stepframe_event(ctx, dst, 2) || scan_stepframe_event(ctx, dst, 3))
goto reset;
break;

/* automatic pause switches to pause_ev, which only supports subset */
case TARGET_COMMAND_PAUSE:
if ((priv->flags & SHMIF_MANUAL_PAUSE) == 0){
Expand Down

0 comments on commit 1776236

Please sign in to comment.