From 93215927a9d3f2bae3b671fba34c406775fb215b Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Wed, 16 Dec 2015 18:13:21 +1100 Subject: [PATCH] glbasememory: add a generic interface for allocating GL memories This is made possible by a subclassable GstGLAllocationParams that holds the allocation parameters Every allocation would now go through gst_gl_base_memory_alloc with the allocation parameters now being specified in a single struct to allow extension by different allocators. --- gst-libs/gst/gl/gstglbasememory.c | 136 ++++++++++++++++++++++++++++++ gst-libs/gst/gl/gstglbasememory.h | 81 ++++++++++++++++-- 2 files changed, 212 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/gl/gstglbasememory.c b/gst-libs/gst/gl/gstglbasememory.c index a674e9a9c5..e2b139e74b 100644 --- a/gst-libs/gst/gl/gstglbasememory.c +++ b/gst-libs/gst/gl/gstglbasememory.c @@ -505,3 +505,139 @@ gst_gl_base_memory_memcpy (GstGLBaseMemory * src, GstGLBaseMemory * dest, return TRUE; } + +/** + * gst_gl_allocation_params_init: + * @params: the #GstGLAllocationParams to initialize + * @struct_size: the struct size of the implementation + * @alloc: some alloc flags + * @copy: a copy function + * @free: a free function + * @context: (transfer none): a #GstGLContext + * @alloc_size: the number of bytes to allocate. + * @alloc_params: (transfer none) (allow-none): a #GstAllocationParams to apply + * @notify: (allow-none): a #GDestroyNotify + * @user_data: (transfer none) (allow-none): user data to call @notify with + * @wrapped_data: (transfer none) (allow-none): a sysmem data pointer to initialize the allocation with + * @gl_handle: (transfer none): a GL handle to initialize the allocation with + * + * @notify will be called once for each allocated memory using these @params + * when freeing the memory. + * + * Returns: whether the paramaters could be initialized + */ +gboolean +gst_gl_allocation_params_init (GstGLAllocationParams * params, + gsize struct_size, guint alloc_flags, GstGLAllocationParamsCopyFunc copy, + GstGLAllocationParamsFreeFunc free, GstGLContext * context, + gsize alloc_size, GstAllocationParams * alloc_params, + GDestroyNotify notify, gpointer user_data, gpointer wrapped_data, + guint gl_handle) +{ + memset (params, 0, sizeof (*params)); + + g_return_val_if_fail (struct_size > 0, FALSE); + g_return_val_if_fail (copy != NULL, FALSE); + g_return_val_if_fail (free != NULL, FALSE); + g_return_val_if_fail (GST_IS_GL_CONTEXT (context), FALSE); + + params->struct_size = struct_size; + params->alloc_size = alloc_size; + params->copy = copy; + params->free = free; + params->alloc_flags = alloc_flags; + params->context = gst_object_ref (context); + if (alloc_params) + params->alloc_params = gst_allocation_params_copy (alloc_params); + params->notify = notify; + params->user_data = user_data; + params->wrapped_data = wrapped_data; + params->gl_handle = gl_handle; + + return TRUE; +} + +/** + * gst_gl_allocation_params_copy: + * @src: the #GstGLAllocationParams to initialize + * + * Returns: a copy of the #GstGLAllocationParams specified by @src or %NULL on + * failure + */ +GstGLAllocationParams * +gst_gl_allocation_params_copy (GstGLAllocationParams * src) +{ + GstGLAllocationParams *dest; + + g_return_val_if_fail (src != NULL, NULL); + + dest = g_malloc0 (src->struct_size); + + if (src->copy) + src->copy (src, dest); + + return dest; +} + +/** + * gst_gl_allocation_params_free: + * @params: the #GstGLAllocationParams to initialize + * + * Frees the #GstGLAllocationParams and all associated data. + */ +void +gst_gl_allocation_params_free (GstGLAllocationParams * params) +{ + if (params->free) + params->free (params); + + g_free (params); +} + +void +gst_gl_allocation_params_free_data (GstGLAllocationParams * params) +{ + if (params->context) + gst_object_unref (params->context); + if (params->alloc_params) + gst_allocation_params_free (params->alloc_params); +} + +void +gst_gl_allocation_params_copy_data (GstGLAllocationParams * src, + GstGLAllocationParams * dest) +{ + gst_gl_allocation_params_init (dest, src->struct_size, src->alloc_flags, + src->copy, src->free, NULL, src->alloc_size, NULL, src->notify, + src->user_data, src->wrapped_data, src->gl_handle); + + if (src->context) + dest->context = gst_object_ref (src->context); + if (src->alloc_params) + dest->alloc_params = gst_allocation_params_copy (src->alloc_params); +} + +G_DEFINE_BOXED_TYPE (GstGLAllocationParams, gst_gl_allocation_params, + (GBoxedCopyFunc) gst_gl_allocation_params_copy, + (GBoxedFreeFunc) gst_gl_allocation_params_free); + +/** + * gst_gl_base_memory_alloc: + * @allocator: a #GstGLBaseMemoryAllocator + * @params: the #GstGLAllocationParams to allocate the memory with + * + * Returns: a new #GstGLBaseMemory from @allocator with the requested @params. + */ +GstGLBaseMemory * +gst_gl_base_memory_alloc (GstGLBaseMemoryAllocator * allocator, + GstGLAllocationParams * params) +{ + GstGLBaseMemoryAllocatorClass *alloc_class; + + alloc_class = GST_GL_BASE_MEMORY_ALLOCATOR_GET_CLASS (allocator); + + g_return_val_if_fail (alloc_class != NULL, NULL); + g_return_val_if_fail (alloc_class->alloc != NULL, NULL); + + return alloc_class->alloc (allocator, params); +} diff --git a/gst-libs/gst/gl/gstglbasememory.h b/gst-libs/gst/gl/gstglbasememory.h index 1df0ac3a44..b6d1cabe8c 100644 --- a/gst-libs/gst/gl/gstglbasememory.h +++ b/gst-libs/gst/gl/gstglbasememory.h @@ -97,11 +97,77 @@ struct _GstGLBaseMemory gpointer user_data; }; -typedef gboolean (*GstGLBaseMemoryAllocatorCreateFunction) (GstGLBaseMemory * mem, GError ** error); -typedef gpointer (*GstGLBaseMemoryAllocatorMapFunction) (GstGLBaseMemory * mem, GstMapInfo * info, gsize maxsize); -typedef void (*GstGLBaseMemoryAllocatorUnmapFunction) (GstGLBaseMemory * mem, GstMapInfo * info); -typedef GstGLBaseMemory * (*GstGLBaseMemoryAllocatorCopyFunction) (GstGLBaseMemory * mem, gssize offset, gssize size); -typedef void (*GstGLBaseMemoryAllocatorDestroyFunction) (GstGLBaseMemory * mem); +typedef struct _GstGLAllocationParams GstGLAllocationParams; +/* subclass has to compose with the parent class */ +typedef void (*GstGLAllocationParamsCopyFunc) (GstGLAllocationParams * src, GstGLAllocationParams * dest); +/* subclass has to compose with the parent class */ +typedef void (*GstGLAllocationParamsFreeFunc) (gpointer params); + +#define GST_TYPE_GL_ALLOCATION_PARAMS (gst_gl_allocation_params_get_type()) +GType gst_gl_allocation_params_get_type (void); + +#define GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_ALLOC (1 << 0) +#define GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_SYSMEM (1 << 1) +#define GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_GPU_HANDLE (1 << 2) +#define GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_USER (1 << 16) + +/* Because GstAllocationParams is not subclassable, start our own subclass + * chain. FIXME: 2.0 make GstAllocationParams subclassable */ +struct _GstGLAllocationParams +{ + gsize struct_size; + GstGLAllocationParamsCopyFunc copy; + GstGLAllocationParamsFreeFunc free; + + guint alloc_flags; + gsize alloc_size; + GstAllocationParams *alloc_params; + GstGLContext *context; + GDestroyNotify notify; + gpointer user_data; + + /* GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_SYSMEM only */ + gpointer wrapped_data; + /* GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_GPU_HANDLE only */ + guint gl_handle; +}; + +gboolean gst_gl_allocation_params_init (GstGLAllocationParams * params, + gsize struct_size, + guint alloc_flags, + GstGLAllocationParamsCopyFunc copy, + GstGLAllocationParamsFreeFunc free, + GstGLContext * context, + gsize alloc_size, + GstAllocationParams * alloc_params, + GDestroyNotify notify, + gpointer user_data, + gpointer wrapped_data, + guint gl_handle); + +/* free with gst_gl_allocation_params_free */ +GstGLAllocationParams * gst_gl_allocation_params_copy (GstGLAllocationParams * src); +void gst_gl_allocation_params_free (GstGLAllocationParams * params); + +/* subclass usage */ +void gst_gl_allocation_params_free_data (GstGLAllocationParams * params); +/* subclass usage */ +void gst_gl_allocation_params_copy_data (GstGLAllocationParams * src, + GstGLAllocationParams * dest); + +typedef GstGLBaseMemory * (*GstGLBaseMemoryAllocatorAllocFunction) (GstGLBaseMemoryAllocator * allocator, + GstGLAllocationParams * params); +typedef gboolean (*GstGLBaseMemoryAllocatorCreateFunction) (GstGLBaseMemory * mem, + GError ** error); +typedef gpointer (*GstGLBaseMemoryAllocatorMapFunction) (GstGLBaseMemory * mem, + GstMapInfo * info, + gsize maxsize); +typedef void (*GstGLBaseMemoryAllocatorUnmapFunction) (GstGLBaseMemory * mem, + GstMapInfo * info); +typedef GstGLBaseMemory * (*GstGLBaseMemoryAllocatorCopyFunction) (GstGLBaseMemory * mem, + gssize offset, + gssize size); +typedef void (*GstGLBaseMemoryAllocatorDestroyFunction) (GstGLBaseMemory * mem); /** * GstGLBaseMemoryAllocator @@ -123,6 +189,8 @@ struct _GstGLBaseMemoryAllocatorClass { GstAllocatorClass parent_class; + GstGLBaseMemoryAllocatorAllocFunction alloc; + GstGLBaseMemoryAllocatorCreateFunction create; GstGLBaseMemoryAllocatorMapFunction map; #if 0 @@ -161,6 +229,9 @@ gboolean gst_gl_base_memory_memcpy (GstGLBaseMemory * src, gssize offset, gssize size); +GstGLBaseMemory * gst_gl_base_memory_alloc (GstGLBaseMemoryAllocator * allocator, + GstGLAllocationParams * params); + G_END_DECLS #endif /* _GST_GL_BUFFER_H_ */