From 10985880c2297ea325037f2a3e698a24bf809b96 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Wed, 8 Apr 2015 13:41:35 -0400 Subject: [PATCH] ecore-drm: Add 2 new API functions for setting and sending framebuffers Summary: This adds 2 new API functions we can use from within the evas drm engine to set framebuffers as current, and to call a pageflip on given buffers. @feature Signed-off-by: Chris Michael --- src/lib/ecore_drm/Ecore_Drm.h | 33 ++++++++++++++++++++ src/lib/ecore_drm/ecore_drm_fb.c | 67 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/src/lib/ecore_drm/Ecore_Drm.h b/src/lib/ecore_drm/Ecore_Drm.h index b28e7f1..1f9a72e 100644 --- a/src/lib/ecore_drm/Ecore_Drm.h +++ b/src/lib/ecore_drm/Ecore_Drm.h @@ -173,6 +173,9 @@ typedef struct _Ecore_Drm_Event_Activate Ecore_Drm_Event_Activate; /** @since 1.14 */ typedef struct _Ecore_Drm_Event_Output Ecore_Drm_Event_Output; +/** @since 1.15 */ +typedef void (*Ecore_Drm_Pageflip_Cb)(void *data); + EAPI extern int ECORE_DRM_EVENT_ACTIVATE; EAPI extern int ECORE_DRM_EVENT_OUTPUT; /**< @since 1.14 */ @@ -576,6 +579,36 @@ EAPI void ecore_drm_fb_destroy(Ecore_Drm_Fb *fb); */ EAPI void ecore_drm_fb_dirty(Ecore_Drm_Fb *fb, Eina_Rectangle *rects, unsigned int count); +/** + * Set an Ecore_Drm_Fb as the current framebuffer + * + * This function will set the given Ecore_Drm_Fb as the framebuffer used + * across all outputs + * + * @param dev The Ecore_Drm_Device to use + * @param fb The Ecore_Drm_Fb to make the current framebuffer + * + * @ingroup Ecore_Drm_Fb_Group + * @since 1.15 + */ +EAPI void ecore_drm_fb_set(Ecore_Drm_Device *dev, Ecore_Drm_Fb *fb); + +/** + * Send an Ecore_Drm_Fb to the Ecore_Drm_Device + * + * This function will call drmModePageFlip for the given device using the + * given Ecore_Drm_Fb as the framebuffer + * + * @param dev The Ecore_Drm_Device to use + * @param fb The Ecore_Drm_Fb to send + * @param cb The function to call when the page flip has completed + * @param data The data to pass to the callback function + * + * @ingroup Ecore_Drm_Fb_Group + * @since 1.15 + */ +EAPI void ecore_drm_fb_send(Ecore_Drm_Device *dev, Ecore_Drm_Fb *fb, Ecore_Drm_Pageflip_Cb func, void *data); + EAPI Eina_Bool ecore_drm_launcher_connect(Ecore_Drm_Device *dev); EAPI void ecore_drm_launcher_disconnect(Ecore_Drm_Device *dev); diff --git a/src/lib/ecore_drm/ecore_drm_fb.c b/src/lib/ecore_drm/ecore_drm_fb.c index da6b421..ea466ca 100644 --- a/src/lib/ecore_drm/ecore_drm_fb.c +++ b/src/lib/ecore_drm/ecore_drm_fb.c @@ -162,3 +162,70 @@ ecore_drm_fb_dirty(Ecore_Drm_Fb *fb, Eina_Rectangle *rects, unsigned int count) } #endif } + +EAPI void +ecore_drm_fb_set(Ecore_Drm_Device *dev, Ecore_Drm_Fb *fb) +{ + Ecore_Drm_Output *output; + Eina_List *l; + + EINA_SAFETY_ON_NULL_RETURN(dev); + EINA_SAFETY_ON_NULL_RETURN(fb); + + if ((fb->w != dev->dumb[0]->w) || (fb->h != dev->dumb[0]->h)) + { + /* we need to copy from fb to dev->dumb */ + CRIT("Trying to set a Framebuffer of improper size !!"); + return; + } + + EINA_LIST_FOREACH(dev->outputs, l, output) + { + int x = 0, y = 0; + + if (!output->cloned) + { + x = output->x; + y = output->y; + } + + if (drmModeSetCrtc(dev->drm.fd, output->crtc_id, fb->id, x, y, + &output->conn_id, 1, &output->current_mode->info)) + { + ERR("Failed to set Mode %dx%d for Output %s: %m", + output->current_mode->width, output->current_mode->height, + output->name); + } + } +} + +EAPI void +ecore_drm_fb_send(Ecore_Drm_Device *dev, Ecore_Drm_Fb *fb, Ecore_Drm_Pageflip_Cb func, void *data) +{ + Ecore_Drm_Output *output; + Eina_List *l; + Ecore_Drm_Pageflip_Callback *cb; + + EINA_SAFETY_ON_NULL_RETURN(dev); + EINA_SAFETY_ON_NULL_RETURN(fb); + EINA_SAFETY_ON_NULL_RETURN(func); + + if (eina_list_count(dev->outputs) < 1) return; + + if (!(cb = calloc(1, sizeof(Ecore_Drm_Pageflip_Callback)))) + return; + + cb->func = func; + cb->data = data; + cb->count = eina_list_count(dev->outputs); + + EINA_LIST_FOREACH(dev->outputs, l, output) + { + if (drmModePageFlip(dev->drm.fd, output->crtc_id, fb->id, + DRM_MODE_PAGE_FLIP_EVENT, cb) < 0) + { + ERR("Cannot flip crtc %u for connector %u: %m", + output->crtc_id, output->conn_id); + } + } +} -- 2.7.4