From b4cbf860b9d483f7ad7a50c672a000927cb2b39f Mon Sep 17 00:00:00 2001 From: Derek Foreman Date: Wed, 7 Sep 2016 22:24:45 -0500 Subject: [PATCH] ecore_drm2: Add a page flip completion call Add a function for ecore_evas_drm to call after a page flip happens so ecore_drm2 can track busy status for fbs itself (including for the fb that's currently being flipped to scanout) Also, call the completion function from ecore_evas_drm --- src/lib/ecore_drm2/Ecore_Drm2.h | 15 ++++++++++++ src/lib/ecore_drm2/ecore_drm2_fb.c | 27 +++++++++++++++++++--- src/lib/ecore_drm2/ecore_drm2_private.h | 2 +- .../ecore_evas/engines/drm/ecore_evas_drm.c | 2 ++ 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/lib/ecore_drm2/Ecore_Drm2.h b/src/lib/ecore_drm2/Ecore_Drm2.h index 0a8411f..013abb0 100644 --- a/src/lib/ecore_drm2/Ecore_Drm2.h +++ b/src/lib/ecore_drm2/Ecore_Drm2.h @@ -768,6 +768,9 @@ EAPI void ecore_drm2_fb_dirty(Ecore_Drm2_Fb *fb, Eina_Rectangle *rects, unsigned /** * Schedule a pageflip to the given Ecore_Drm2_Fb * + * The caller is responsible for running a page flip handler + * and calling ecore_drm2_fb_flip_complete() when it completes. + * * @param fb * @param output * @@ -779,6 +782,18 @@ EAPI void ecore_drm2_fb_dirty(Ecore_Drm2_Fb *fb, Eina_Rectangle *rects, unsigned EAPI int ecore_drm2_fb_flip(Ecore_Drm2_Fb *fb, Ecore_Drm2_Output *output); /** + * Must be called by a page flip handler when the flip completes. + * + * @param output + * + * @return Whether there's an undisplayed buffer still in the queue. + * + * @ingroup Ecore_Drm2_Fb_Group + * @since 1.18 + */ +EAPI Eina_Bool ecore_drm2_fb_flip_complete(Ecore_Drm2_Output *output); + +/** * Return the Ecore_Drm2_Fb's busy status * * @param fb diff --git a/src/lib/ecore_drm2/ecore_drm2_fb.c b/src/lib/ecore_drm2/ecore_drm2_fb.c index b56486e..f660f05 100644 --- a/src/lib/ecore_drm2/ecore_drm2_fb.c +++ b/src/lib/ecore_drm2/ecore_drm2_fb.c @@ -223,6 +223,19 @@ ecore_drm2_fb_dirty(Ecore_Drm2_Fb *fb, Eina_Rectangle *rects, unsigned int count #endif } +EAPI Eina_Bool +ecore_drm2_fb_flip_complete(Ecore_Drm2_Output *output) +{ + if (output->current) output->current->busy = EINA_FALSE; + output->current = output->pending; + output->pending = NULL; + + /* In case they were the same buffer... */ + if (output->current) output->current->busy = EINA_TRUE; + + return !!output->next; +} + EAPI int ecore_drm2_fb_flip(Ecore_Drm2_Fb *fb, Ecore_Drm2_Output *output) { @@ -233,6 +246,13 @@ ecore_drm2_fb_flip(Ecore_Drm2_Fb *fb, Ecore_Drm2_Output *output) if (!output->enabled) return -1; + if (output->pending) + { + if (output->next) output->next->busy = EINA_FALSE; + output->next = fb; + if (output->next) output->next->busy = EINA_TRUE; + return 0; + } if (!fb) fb = output->next; /* So we can generate a tick by flipping to the current fb */ @@ -262,7 +282,9 @@ ecore_drm2_fb_flip(Ecore_Drm2_Fb *fb, Ecore_Drm2_Output *output) return ret; } + if (output->current) output->current->busy = EINA_FALSE; output->current = fb; + output->current->busy = EINA_TRUE; output->next = NULL; return 0; @@ -284,9 +306,8 @@ ecore_drm2_fb_flip(Ecore_Drm2_Fb *fb, Ecore_Drm2_Output *output) return 0; } - if (output->current) output->current->busy = EINA_FALSE; - output->current = fb; - fb->busy = EINA_TRUE; + output->pending = fb; + output->pending->busy = EINA_TRUE; return 0; } diff --git a/src/lib/ecore_drm2/ecore_drm2_private.h b/src/lib/ecore_drm2/ecore_drm2_private.h index 8c16c04..96acfa4 100644 --- a/src/lib/ecore_drm2/ecore_drm2_private.h +++ b/src/lib/ecore_drm2/ecore_drm2_private.h @@ -138,7 +138,7 @@ struct _Ecore_Drm2_Output drmModeCrtcPtr ocrtc; - Ecore_Drm2_Fb *current, *next; + Ecore_Drm2_Fb *current, *next, *pending; Eina_Matrix4 matrix, inverse; Ecore_Drm2_Transform transform; diff --git a/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c b/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c index 9b456b7..90a3444 100644 --- a/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c +++ b/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c @@ -639,6 +639,8 @@ _cb_pageflip(int fd EINA_UNUSED, unsigned int frame EINA_UNUSED, unsigned int se ee = data; edata = ee->engine.data; + ecore_drm2_fb_flip_complete(edata->output); + next = ecore_drm2_output_next_fb_get(edata->output); if (next) { -- 2.7.4