evas: Add a function to block for render thread completion
authorDerek Foreman <derekf@osg.samsung.com>
Wed, 26 Apr 2017 18:44:33 +0000 (13:44 -0500)
committerDerek Foreman <derekf@osg.samsung.com>
Wed, 26 Apr 2017 18:47:46 +0000 (13:47 -0500)
This is needed by dmabuf engine fallback when it realizes it locally
allocated a buffer, has been rendering to it, but the compositor can't use
it.

So the engine copies its buffer contents into a new wl_shm buffer and
continues from there - however we need to make sure the async renderer
has finished first, so we don't copy a partial buffer.

This allows us to block for all previously submit actions in the render
queue to complete.

src/lib/evas/common/evas_thread_render.c
src/lib/evas/include/evas_common_private.h

index 8595566..2104042 100644 (file)
@@ -72,6 +72,47 @@ evas_thread_queue_flush(Evas_Thread_Command_Cb cb, void *data)
    evas_thread_queue_append(cb, data, EINA_TRUE);
 }
 
+struct fence_stuff {
+   Eina_Lock lock;
+   Eina_Condition cond;
+};
+
+static void
+_evas_thread_queue_fence(void *data)
+{
+   struct fence_stuff *f;
+
+   f = data;
+
+   eina_lock_take(&f->lock);
+   eina_condition_signal(&f->cond);
+   eina_lock_release(&f->lock);
+}
+
+EAPI void
+evas_thread_queue_wait(void)
+{
+   struct fence_stuff f;
+
+   /* No shortcuts here - if the thread queue looks empty it could just mean
+    * it's being processed.  Need a round trip.
+    */
+   if (!eina_lock_new(&f.lock)) return;
+   if (!eina_condition_new(&f.cond, &f.lock))
+     {
+        eina_lock_free(&f.lock);
+        return;
+     }
+
+   eina_lock_take(&f.lock);
+   evas_thread_queue_flush(_evas_thread_queue_fence, &f);
+   eina_condition_wait(&f.cond);
+   eina_lock_release(&f.lock);
+
+   eina_lock_free(&f.lock);
+   eina_condition_free(&f.cond);
+}
+
 static void*
 evas_thread_worker_func(void *data EINA_UNUSED, Eina_Thread thread EINA_UNUSED)
 {
index 829c510..ceb1095 100644 (file)
@@ -1328,6 +1328,7 @@ int               evas_thread_init(void);
 int               evas_thread_shutdown(void);
 EAPI void         evas_thread_cmd_enqueue(Evas_Thread_Command_Cb cb, void *data);
 EAPI void         evas_thread_queue_flush(Evas_Thread_Command_Cb cb, void *data);
+EAPI void         evas_thread_queue_wait(void);
 
 typedef enum _Evas_Render_Mode
 {