ecore_drm2: Add release handlers for buffers
authorDerek Foreman <derekf@osg.samsung.com>
Fri, 9 Sep 2016 18:31:20 +0000 (13:31 -0500)
committerDerek Foreman <derekf@osg.samsung.com>
Fri, 9 Sep 2016 18:39:05 +0000 (13:39 -0500)
Allow the engine to register a callback for buffer release.  This lets us
do appropriate buffer bookkeeping (for example, gbm locking) in the
engine.

src/lib/ecore_drm2/Ecore_Drm2.h
src/lib/ecore_drm2/ecore_drm2_fb.c
src/lib/ecore_drm2/ecore_drm2_outputs.c
src/lib/ecore_drm2/ecore_drm2_private.h

index 99a2e9a..587f17f 100644 (file)
@@ -61,6 +61,8 @@ typedef struct _Ecore_Drm2_Event_Activate
 EAPI extern int ECORE_DRM2_EVENT_OUTPUT_CHANGED;
 EAPI extern int ECORE_DRM2_EVENT_ACTIVATE;
 
+typedef void (*Ecore_Drm2_Release_Handler)(void *data, Ecore_Drm2_Fb *b);
+
 /**
  * @file
  * @brief Ecore functions for dealing with drm, virtual terminals
@@ -809,6 +811,20 @@ EAPI void ecore_drm2_fb_busy_set(Ecore_Drm2_Fb *fb, Eina_Bool busy);
 EAPI void ecore_drm2_output_user_data_set(Ecore_Drm2_Output *o, void *data);
 
 /**
+ * Register a callback for the buffer release handler
+ *
+ * When a flip completes ecore_drm2 may release a buffer.  Use this callback
+ * if you need to do bookkeeping or locking on buffer release.
+ *
+ * @param output The output to register the callback on
+ * @param handler The function to handle the callback
+ * @param data The user data to pass to the callback
+ * @ingroup Ecore_Drm2_Output_Group
+ * @since 1.19
+ */
+EAPI void ecore_drm2_output_release_handler_set(Ecore_Drm2_Output *output, Ecore_Drm2_Release_Handler handler, void *data);
+
+/**
  * Get the Framebuffer's gbm buffer object
  *
  * @param fb The framebuffer to query
index d772768..aedef9f 100644 (file)
@@ -224,16 +224,20 @@ ecore_drm2_fb_dirty(Ecore_Drm2_Fb *fb, Eina_Rectangle *rects, unsigned int count
 #endif
 }
 
+static void _release_buffer(Ecore_Drm2_Output *output, Ecore_Drm2_Fb *b)
+{
+   b->busy = EINA_FALSE;
+   if (output->release_cb) output->release_cb(output->release_data, b);
+}
+
 EAPI Eina_Bool
 ecore_drm2_fb_flip_complete(Ecore_Drm2_Output *output)
 {
-   if (output->current) output->current->busy = EINA_FALSE;
+   if (output->current && (output->current != output->pending))
+     _release_buffer(output, output->current);
    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;
 }
 
@@ -249,7 +253,7 @@ ecore_drm2_fb_flip(Ecore_Drm2_Fb *fb, Ecore_Drm2_Output *output)
 
    if (output->pending)
      {
-        if (output->next) output->next->busy = EINA_FALSE;
+        if (output->next) _release_buffer(output, output->next);
         output->next = fb;
         if (output->next) output->next->busy = EINA_TRUE;
         return 0;
@@ -283,7 +287,7 @@ ecore_drm2_fb_flip(Ecore_Drm2_Fb *fb, Ecore_Drm2_Output *output)
              return ret;
           }
 
-        if (output->current) output->current->busy = EINA_FALSE;
+        if (output->current) _release_buffer(output, output->current);
         output->current = fb;
         output->current->busy = EINA_TRUE;
         output->next = NULL;
index 3f32092..dff7461 100644 (file)
@@ -1202,3 +1202,10 @@ ecore_drm2_output_user_data_set(Ecore_Drm2_Output *o, void *data)
 {
    o->user_data = data;
 }
+
+EAPI void
+ecore_drm2_output_release_handler_set(Ecore_Drm2_Output *o, Ecore_Drm2_Release_Handler cb, void *data)
+{
+   o->release_data = data;
+   o->release_cb = cb;
+}
index d78d011..bce5ede 100644 (file)
@@ -154,6 +154,8 @@ struct _Ecore_Drm2_Output
    Eina_List *planes;
 
    void *user_data;
+   Ecore_Drm2_Release_Handler release_cb;
+   void *release_data;
 
    Eina_Bool connected : 1;
    Eina_Bool primary : 1;