ecore_drm2: Add a fallback method for vblank waiting
We can't depend on vblank waits being implemented by the driver, but we can count on page flips functioning, so add a fallback that does a page flip and waits for it.
This commit is contained in:
parent
6bb56b3f56
commit
0584fc81a2
|
@ -1583,6 +1583,49 @@ ecore_drm2_output_subpixel_get(const Ecore_Drm2_Output *output)
|
||||||
return output->subpixel;
|
return output->subpixel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_blank_fallback_handler(int fd EINA_UNUSED, unsigned int frame EINA_UNUSED, unsigned int sec, unsigned int usec, void *data EINA_UNUSED)
|
||||||
|
{
|
||||||
|
Ecore_Drm2_Output *output;
|
||||||
|
|
||||||
|
output = data;
|
||||||
|
output->fallback_usec = usec;
|
||||||
|
output->fallback_sec = sec;
|
||||||
|
}
|
||||||
|
static int
|
||||||
|
_blanktime_fallback(Ecore_Drm2_Output *output, int sequence, long *sec, long *usec)
|
||||||
|
{
|
||||||
|
drmEventContext ctx;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Too lazy to loop for > 1, and don't want to block for < 1 */
|
||||||
|
if (sequence != 1) return -1;
|
||||||
|
|
||||||
|
/* If we got here with a flip waiting to complete we can do nothing. */
|
||||||
|
if (output->pending.fb) return -1;
|
||||||
|
|
||||||
|
if (!output->current.fb) return -1;
|
||||||
|
|
||||||
|
memset(&ctx, 0, sizeof(ctx));
|
||||||
|
ctx.version = 2;
|
||||||
|
ctx.page_flip_handler = _blank_fallback_handler;
|
||||||
|
ctx.vblank_handler = NULL;
|
||||||
|
|
||||||
|
ret = sym_drmModePageFlip(output->current.fb->fd, output->crtc_id,
|
||||||
|
output->current.fb->id, DRM_MODE_PAGE_FLIP_EVENT,
|
||||||
|
output);
|
||||||
|
if (ret < 0) return -1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ret = sym_drmHandleEvent(output->current.fb->fd, &ctx);
|
||||||
|
} while (ret != 0 && errno == EAGAIN);
|
||||||
|
if (ret < 0) return -1;
|
||||||
|
|
||||||
|
*sec = output->fallback_sec;
|
||||||
|
*usec = output->fallback_usec;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
EAPI Eina_Bool
|
EAPI Eina_Bool
|
||||||
ecore_drm2_output_blanktime_get(Ecore_Drm2_Output *output, int sequence, long *sec, long *usec)
|
ecore_drm2_output_blanktime_get(Ecore_Drm2_Output *output, int sequence, long *sec, long *usec)
|
||||||
{
|
{
|
||||||
|
@ -1597,6 +1640,12 @@ ecore_drm2_output_blanktime_get(Ecore_Drm2_Output *output, int sequence, long *s
|
||||||
v.request.type = DRM_VBLANK_RELATIVE;
|
v.request.type = DRM_VBLANK_RELATIVE;
|
||||||
v.request.sequence = sequence;
|
v.request.sequence = sequence;
|
||||||
ret = sym_drmWaitVBlank(output->fd, &v);
|
ret = sym_drmWaitVBlank(output->fd, &v);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
ret = _blanktime_fallback(output, sequence, sec, usec);
|
||||||
|
if (ret) return EINA_FALSE;
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
if (ret) return EINA_FALSE;
|
if (ret) return EINA_FALSE;
|
||||||
if (v.reply.tval_sec < 0) return EINA_FALSE;
|
if (v.reply.tval_sec < 0) return EINA_FALSE;
|
||||||
if (v.reply.tval_usec < 0) return EINA_FALSE;
|
if (v.reply.tval_usec < 0) return EINA_FALSE;
|
||||||
|
|
|
@ -209,6 +209,8 @@ struct _Ecore_Drm2_Output
|
||||||
int pipe;
|
int pipe;
|
||||||
int x, y, w, h, pw, ph;
|
int x, y, w, h, pw, ph;
|
||||||
|
|
||||||
|
long fallback_sec, fallback_usec;
|
||||||
|
|
||||||
uint32_t subpixel;
|
uint32_t subpixel;
|
||||||
uint32_t crtc_id, conn_id, conn_type;
|
uint32_t crtc_id, conn_id, conn_type;
|
||||||
uint32_t scale;
|
uint32_t scale;
|
||||||
|
|
Loading…
Reference in New Issue