glsyncmeta: add vfuncs for all operations
authorMatthew Waters <matthew@centricular.com>
Mon, 2 Nov 2015 06:57:29 +0000 (17:57 +1100)
committerMatthew Waters <matthew@centricular.com>
Tue, 17 Nov 2015 04:27:26 +0000 (15:27 +1100)
there could be other ways/requirements for synchronising two GPU command
streams (whether GL or platform specific).

e.g. glfencesync/eglwaitnative/cond/etc

gst-libs/gst/gl/gstglsyncmeta.c
gst-libs/gst/gl/gstglsyncmeta.h

index 23bc306..66b5c2a 100644 (file)
@@ -38,8 +38,67 @@ GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
 #define GL_TIMEOUT_EXPIRED 0x911B
 #endif
 
+static void
+_default_set_sync_gl (GstGLSyncMeta * sync_meta, GstGLContext * context)
+{
+  const GstGLFuncs *gl = context->gl_vtable;
+
+  if (gl->FenceSync) {
+    if (sync_meta->data) {
+      GST_LOG ("deleting sync object %p", sync_meta->data);
+      gl->DeleteSync ((GLsync) sync_meta->data);
+    }
+    sync_meta->data =
+        (gpointer) gl->FenceSync (GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+    gl->Flush ();
+    GST_LOG ("setting sync object %p", sync_meta->data);
+  } else {
+    gl->Finish ();
+  }
+}
+
+static void
+_default_wait_gl (GstGLSyncMeta * sync_meta, GstGLContext * context)
+{
+  const GstGLFuncs *gl = context->gl_vtable;
+  GLenum res;
+
+  if (sync_meta->data && gl->ClientWaitSync) {
+    do {
+      GST_LOG ("waiting on sync object %p", sync_meta->data);
+      res =
+          gl->ClientWaitSync ((GLsync) sync_meta->data,
+          GL_SYNC_FLUSH_COMMANDS_BIT, 1000000000 /* 1s */ );
+    } while (res == GL_TIMEOUT_EXPIRED);
+  }
+}
+
+static void
+_default_copy (GstGLSyncMeta * src, GstBuffer * sbuffer, GstGLSyncMeta * dest,
+    GstBuffer * dbuffer)
+{
+  GST_LOG ("copy sync object %p from meta %p to %p", src->data, src, dest);
+
+  /* Setting a sync point here relies on GstBuffer copying
+   * metas after data */
+  gst_gl_sync_meta_set_sync_point (src, src->context);
+}
+
+static void
+_default_free_gl (GstGLSyncMeta * sync_meta, GstGLContext * context)
+{
+  const GstGLFuncs *gl = context->gl_vtable;
+
+  if (sync_meta->data) {
+    GST_LOG ("deleting sync object %p", sync_meta->data);
+    gl->DeleteSync ((GLsync) sync_meta->data);
+    sync_meta->data = NULL;
+  }
+}
+
 GstGLSyncMeta *
-gst_buffer_add_gl_sync_meta (GstGLContext * context, GstBuffer * buffer)
+gst_buffer_add_gl_sync_meta_full (GstGLContext * context, GstBuffer * buffer,
+    gpointer data)
 {
   GstGLSyncMeta *meta;
 
@@ -53,60 +112,61 @@ gst_buffer_add_gl_sync_meta (GstGLContext * context, GstBuffer * buffer)
     return NULL;
 
   meta->context = gst_object_ref (context);
-  meta->glsync = NULL;
+  meta->data = data;
 
   return meta;
 }
 
+GstGLSyncMeta *
+gst_buffer_add_gl_sync_meta (GstGLContext * context, GstBuffer * buffer)
+{
+  GstGLSyncMeta *ret = gst_buffer_add_gl_sync_meta_full (context, buffer, NULL);
+  if (!ret)
+    return NULL;
+
+  ret->set_sync_gl = _default_set_sync_gl;
+  ret->wait_gl = _default_wait_gl;
+  ret->copy = _default_copy;
+  ret->free_gl = _default_free_gl;
+}
+
 static void
 _set_sync_point (GstGLContext * context, GstGLSyncMeta * sync_meta)
 {
-  const GstGLFuncs *gl = context->gl_vtable;
+  g_assert (sync_meta->set_sync_gl != NULL);
 
-  if (gl->FenceSync) {
-    if (sync_meta->glsync) {
-      GST_LOG ("deleting sync object %p", sync_meta->glsync);
-      gl->DeleteSync (sync_meta->glsync);
-    }
-    sync_meta->glsync = gl->FenceSync (GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
-    gl->Flush ();
-    GST_LOG ("setting sync object %p", sync_meta->glsync);
-  } else {
-    gl->Finish ();
-  }
+  GST_LOG ("setting sync point %p", sync_meta);
+  sync_meta->set_sync_gl (sync_meta, context);
 }
 
 void
 gst_gl_sync_meta_set_sync_point (GstGLSyncMeta * sync_meta,
     GstGLContext * context)
 {
-  gst_gl_context_thread_add (context,
-      (GstGLContextThreadFunc) _set_sync_point, sync_meta);
+  if (sync_meta->set_sync)
+    sync_meta->set_sync (sync_meta, context);
+  else
+    gst_gl_context_thread_add (context,
+        (GstGLContextThreadFunc) _set_sync_point, sync_meta);
 }
 
 static void
 _wait (GstGLContext * context, GstGLSyncMeta * sync_meta)
 {
-  const GstGLFuncs *gl = context->gl_vtable;
-  GLenum res;
+  g_assert (sync_meta->wait_gl != NULL);
 
-  if (gl->ClientWaitSync) {
-    do {
-      GST_LOG ("waiting on sync object %p", sync_meta->glsync);
-      res =
-          gl->ClientWaitSync (sync_meta->glsync, GL_SYNC_FLUSH_COMMANDS_BIT,
-          1000000000 /* 1s */ );
-    } while (res == GL_TIMEOUT_EXPIRED);
-  }
+  GST_LOG ("waiting %p", sync_meta);
+  sync_meta->wait_gl (sync_meta, context);
 }
 
 void
 gst_gl_sync_meta_wait (GstGLSyncMeta * sync_meta, GstGLContext * context)
 {
-  if (sync_meta->glsync) {
+  if (sync_meta->wait)
+    sync_meta->wait (sync_meta, context);
+  else
     gst_gl_context_thread_add (context,
         (GstGLContextThreadFunc) _wait, sync_meta);
-  }
 }
 
 static gboolean
@@ -120,19 +180,24 @@ _gst_gl_sync_meta_transform (GstBuffer * dest, GstMeta * meta,
   if (GST_META_TRANSFORM_IS_COPY (type)) {
     GstMetaTransformCopy *copy = data;
 
+    g_assert (smeta->copy != NULL);
+
     if (!copy->region) {
       /* only copy if the complete data is copied as well */
-      dmeta = gst_buffer_add_gl_sync_meta (smeta->context, dest);
-
+      dmeta = gst_buffer_add_gl_sync_meta_full (smeta->context, dest, NULL);
       if (!dmeta)
         return FALSE;
 
-      GST_LOG ("copy sync object %p from meta %p to %p", smeta->glsync,
-          smeta, dmeta);
+      dmeta->set_sync = smeta->set_sync;
+      dmeta->set_sync_gl = smeta->set_sync_gl;
+      dmeta->wait = smeta->wait;
+      dmeta->wait_gl = smeta->wait_gl;
+      dmeta->copy = smeta->copy;
+      dmeta->free = smeta->free;
+      dmeta->free_gl = smeta->free_gl;
 
-      /* Setting a sync point here relies on GstBuffer copying
-       * metas after data */
-      gst_gl_sync_meta_set_sync_point (dmeta, smeta->context);
+      GST_LOG ("copying sync meta %p into %p", smeta, dmeta);
+      smeta->copy (smeta, buffer, dmeta, dest);
     }
   } else {
     /* return FALSE, if transform type is not supported */
@@ -145,22 +210,21 @@ _gst_gl_sync_meta_transform (GstBuffer * dest, GstMeta * meta,
 static void
 _free_gl_sync_meta (GstGLContext * context, GstGLSyncMeta * sync_meta)
 {
-  const GstGLFuncs *gl = context->gl_vtable;
+  g_assert (sync_meta->free_gl != NULL);
 
-  if (sync_meta->glsync) {
-    GST_LOG ("deleting sync object %p", sync_meta->glsync);
-    gl->DeleteSync (sync_meta->glsync);
-    sync_meta->glsync = NULL;
-  }
+  GST_LOG ("free sync meta %p", sync_meta);
+  sync_meta->free_gl (sync_meta, context);
 }
 
 static void
 _gst_gl_sync_meta_free (GstGLSyncMeta * sync_meta, GstBuffer * buffer)
 {
-  if (sync_meta->glsync) {
+  if (sync_meta->free)
+    sync_meta->free (sync_meta, sync_meta->context);
+  else
     gst_gl_context_thread_add (sync_meta->context,
         (GstGLContextThreadFunc) _free_gl_sync_meta, sync_meta);
-  }
+
   gst_object_unref (sync_meta->context);
 }
 
@@ -177,7 +241,14 @@ _gst_gl_sync_meta_init (GstGLSyncMeta * sync_meta, gpointer params,
   }
 
   sync_meta->context = NULL;
-  sync_meta->glsync = NULL;
+  sync_meta->data = NULL;
+  sync_meta->set_sync = NULL;
+  sync_meta->set_sync_gl = NULL;
+  sync_meta->wait = NULL;
+  sync_meta->wait_gl = NULL;
+  sync_meta->copy = NULL;
+  sync_meta->free = NULL;
+  sync_meta->free_gl = NULL;
 
   return TRUE;
 }
index 9d79435..8620ccd 100644 (file)
@@ -32,12 +32,19 @@ typedef struct _GstGLSyncMeta GstGLSyncMeta;
 #define GST_BUFFER_POOL_OPTION_GL_SYNC_META "GstBufferPoolOptionGLSyncMeta"
 
 struct _GstGLSyncMeta {
-  /*< private >*/
   GstMeta parent;
 
   GstGLContext *context;
 
-  GLsync        glsync;
+  gpointer      data;
+
+  void (*set_sync) (GstGLSyncMeta * sync, GstGLContext * context);
+  void (*set_sync_gl) (GstGLSyncMeta * sync, GstGLContext * context);
+  void (*wait) (GstGLSyncMeta * sync, GstGLContext * context);
+  void (*wait_gl) (GstGLSyncMeta * sync, GstGLContext * context);
+  void (*copy) (GstGLSyncMeta * src, GstBuffer * sbuffer, GstGLSyncMeta * dest, GstBuffer * dbuffer);
+  void (*free) (GstGLSyncMeta * sync, GstGLContext * context);
+  void (*free_gl) (GstGLSyncMeta * sync, GstGLContext * context);
 };
 
 GType gst_gl_sync_meta_api_get_type (void);
@@ -46,6 +53,8 @@ const GstMetaInfo * gst_gl_sync_meta_get_info (void);
 #define gst_buffer_get_gl_sync_meta(b) ((GstGLSyncMeta*)gst_buffer_get_meta((b),GST_GL_SYNC_META_API_TYPE))
 
 GstGLSyncMeta *     gst_buffer_add_gl_sync_meta         (GstGLContext * context, GstBuffer *buffer);
+GstGLSyncMeta *     gst_buffer_add_gl_sync_meta_full    (GstGLContext * context, GstBuffer * buffer,
+                                                         gpointer data);
 void                gst_gl_sync_meta_set_sync_point     (GstGLSyncMeta * sync, GstGLContext * context);
 void                gst_gl_sync_meta_wait               (GstGLSyncMeta * sync, GstGLContext * context);