From: Matthew Waters Date: Mon, 2 Nov 2015 06:57:29 +0000 (+1100) Subject: glsyncmeta: add vfuncs for all operations X-Git-Tag: 1.19.3~507^2~7571 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=67327615df95e269d1e10588da70ccf4bed4078b;p=platform%2Fupstream%2Fgstreamer.git glsyncmeta: add vfuncs for all operations there could be other ways/requirements for synchronising two GPU command streams (whether GL or platform specific). e.g. glfencesync/eglwaitnative/cond/etc --- diff --git a/gst-libs/gst/gl/gstglsyncmeta.c b/gst-libs/gst/gl/gstglsyncmeta.c index 23bc306..66b5c2a 100644 --- a/gst-libs/gst/gl/gstglsyncmeta.c +++ b/gst-libs/gst/gl/gstglsyncmeta.c @@ -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; } diff --git a/gst-libs/gst/gl/gstglsyncmeta.h b/gst-libs/gst/gl/gstglsyncmeta.h index 9d79435..8620ccd 100644 --- a/gst-libs/gst/gl/gstglsyncmeta.h +++ b/gst-libs/gst/gl/gstglsyncmeta.h @@ -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);