ecore-drm: Add 2 new API functions for setting and sending framebuffers
authorChris Michael <cp.michael@samsung.com>
Wed, 8 Apr 2015 17:41:35 +0000 (13:41 -0400)
committerStefan Schmidt <s.schmidt@samsung.com>
Fri, 10 Apr 2015 09:09:51 +0000 (11:09 +0200)
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 <cp.michael@samsung.com>
src/lib/ecore_drm/Ecore_Drm.h
src/lib/ecore_drm/ecore_drm_fb.c

index b28e7f1..1f9a72e 100644 (file)
@@ -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);
 
index da6b421..ea466ca 100644 (file)
@@ -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);
+          }
+     }
+}