From c1221c468024417d75829a6c2ce8d4e57631ebc6 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 23 Nov 2015 16:18:00 +0900 Subject: [PATCH] ecore_drm: support wait_vblank function and user drm vblank callback Change-Id: I1b5337ee64cb20f44169a50ff7fcd5fd0824b6fb --- src/lib/ecore_drm/Ecore_Drm.h | 3 ++ src/lib/ecore_drm/ecore_drm_device.c | 16 +++------ src/lib/ecore_drm/ecore_drm_output.c | 66 ++++++++++++++++++++++++++++++++++- src/lib/ecore_drm/ecore_drm_private.h | 7 ++++ 4 files changed, 79 insertions(+), 13 deletions(-) diff --git a/src/lib/ecore_drm/Ecore_Drm.h b/src/lib/ecore_drm/Ecore_Drm.h index 0e4f28d..694992e 100644 --- a/src/lib/ecore_drm/Ecore_Drm.h +++ b/src/lib/ecore_drm/Ecore_Drm.h @@ -971,6 +971,9 @@ EAPI Eina_List *ecore_drm_seat_evdev_list_get(Ecore_Drm_Seat *seat); EAPI const char *ecore_drm_evdev_name_get(Ecore_Drm_Evdev *evdev); EAPI const char *ecore_drm_evdev_sysname_get(Ecore_Drm_Evdev *evdev); +typedef void (*Ecore_Drm_VBlank_Cb)(void *data); +EAPI Eina_Bool ecore_drm_output_wait_vblank(Ecore_Drm_Output *output, int interval, Ecore_Drm_VBlank_Cb func, void *data); + /* This is ugly, will remove after rebaseing on 1.14 */ EAPI unsigned int ecore_drm_output_crtc_id_get(Ecore_Drm_Output *output); EAPI void ecore_drm_output_current_fb_info_set(Ecore_Drm_Output *output, unsigned int handle, int w, int h, unsigned int format); diff --git a/src/lib/ecore_drm/ecore_drm_device.c b/src/lib/ecore_drm/ecore_drm_device.c index cb6bfe4..00fad55 100644 --- a/src/lib/ecore_drm/ecore_drm_device.c +++ b/src/lib/ecore_drm/ecore_drm_device.c @@ -58,21 +58,13 @@ _ecore_drm_device_cb_page_flip(int fd EINA_UNUSED, unsigned int frame EINA_UNUSE static void _ecore_drm_device_cb_vblank(int fd EINA_UNUSED, unsigned int frame EINA_UNUSED, unsigned int sec EINA_UNUSED, unsigned int usec EINA_UNUSED, void *data) { - Ecore_Drm_Sprite *sprite; - Ecore_Drm_Output *output; + Ecore_Drm_VBlank_Callback *cb; /* DBG("Drm VBlank Event"); */ - if (!(sprite = data)) return; - - output = sprite->output; - output->pending_vblank = EINA_FALSE; - - ecore_drm_output_fb_release(output, sprite->current_fb); - sprite->current_fb = sprite->next_fb; - sprite->next_fb = NULL; - - if (!output->pending_flip) _ecore_drm_output_frame_finish(output); + if (!(cb = data)) return; + if (cb->func) cb->func(cb->data); + free(cb); } #if 0 diff --git a/src/lib/ecore_drm/ecore_drm_output.c b/src/lib/ecore_drm/ecore_drm_output.c index bac12b8..dce7d26 100644 --- a/src/lib/ecore_drm/ecore_drm_output.c +++ b/src/lib/ecore_drm/ecore_drm_output.c @@ -622,6 +622,26 @@ _ecore_drm_output_free(Ecore_Drm_Output *output) free(output); } +static void +_ecore_drm_output_cb_vblank(void *data) +{ + Ecore_Drm_Sprite *sprite; + Ecore_Drm_Output *output; + + /* DBG("Drm VBlank Event"); */ + + if (!(sprite = data)) return; + + output = sprite->output; + output->pending_vblank = EINA_FALSE; + + ecore_drm_output_fb_release(output, sprite->current_fb); + sprite->current_fb = sprite->next_fb; + sprite->next_fb = NULL; + + if (!output->pending_flip) _ecore_drm_output_frame_finish(output); +} + void _ecore_drm_output_frame_finish(Ecore_Drm_Output *output) { @@ -1075,6 +1095,7 @@ ecore_drm_output_repaint(Ecore_Drm_Output *output) .request.type = (DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT), .request.sequence = 1, }; + Ecore_Drm_VBlank_Callback *cb; if (((!sprite->current_fb) && (!sprite->next_fb)) || (!ecore_drm_sprites_crtc_supported(output, sprite->crtcs))) @@ -1085,7 +1106,14 @@ ecore_drm_output_repaint(Ecore_Drm_Output *output) ecore_drm_sprites_fb_set(sprite, id, flags); - vbl.request.signal = (unsigned long)sprite; + if ((cb = calloc(1, sizeof(Ecore_Drm_VBlank_Callback)))) + { + cb->output = output; + cb->func = _ecore_drm_output_cb_vblank; + cb->data = sprite; + } + + vbl.request.signal = (unsigned long)cb; ret = drmWaitVBlank(dev->drm.fd, &vbl); if (ret) ERR("Error Wait VBlank: %m"); @@ -1513,3 +1541,39 @@ ecore_drm_output_current_fb_info_get(Ecore_Drm_Output *output, unsigned int *han if (format) *format = output->curr_fb_format; } + +EAPI Eina_Bool +ecore_drm_output_wait_vblank(Ecore_Drm_Output *output, int interval, Ecore_Drm_VBlank_Cb func, void *data) +{ + Ecore_Drm_Device *dev; + Ecore_Drm_VBlank_Callback *cb; + drmVBlank vbl; + int ret; + + EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE); + + dev = output->dev; + + if (!(cb = calloc(1, sizeof(Ecore_Drm_VBlank_Callback)))) + return EINA_FALSE; + + cb->output = output; + cb->func = func; + cb->data = data; + + vbl.request.type = (DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT); + if (output->pipe > 0) + vbl.request.type |= DRM_VBLANK_SECONDARY; + vbl.request.sequence = interval; + vbl.request.signal = (unsigned long)cb; + + ret = drmWaitVBlank(dev->drm.fd, &vbl); + if (ret) + { + ERR("Error Wait VBlank: %m"); + return EINA_FALSE; + } + + return EINA_TRUE; +} diff --git a/src/lib/ecore_drm/ecore_drm_private.h b/src/lib/ecore_drm/ecore_drm_private.h index a856aeb..2513777 100644 --- a/src/lib/ecore_drm/ecore_drm_private.h +++ b/src/lib/ecore_drm/ecore_drm_private.h @@ -88,6 +88,13 @@ typedef struct _Ecore_Drm_Pageflip_Callback int count; } Ecore_Drm_Pageflip_Callback; +typedef struct _Ecore_Drm_VBlank_Callback +{ + Ecore_Drm_Output *output; + Ecore_Drm_VBlank_Cb func; + void *data; +} Ecore_Drm_VBlank_Callback; + typedef enum _Ecore_Drm_Backlight_Type { ECORE_DRM_BACKLIGHT_RAW, -- 2.7.4