vulkan: implement caching and reuse of a couple of vulkan resources
authorMatthew Waters <matthew@centricular.com>
Tue, 26 Nov 2019 13:25:16 +0000 (00:25 +1100)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Thu, 28 Nov 2019 23:27:21 +0000 (23:27 +0000)
Includes a new GstVulkanHandlePool base class for pooling different
resources togther.  The descriptor cache object is ported to
GstVulkanHandlePool with the exact same functionality.

A new GstVulkanFenceCache is also implemented for caching fences
which is used internally by GstVulkanDevice for creating or reusing
fences.

The existing GstVulkanTrashFenceList object now caches trash objects.

24 files changed:
ext/vulkan/vkcolorconvert.c
ext/vulkan/vkdownload.c
ext/vulkan/vkfullscreenquad.c
ext/vulkan/vkupload.c
ext/vulkan/vkviewconvert.c
gst-libs/gst/vulkan/gstvkdescriptorcache-private.h [deleted file]
gst-libs/gst/vulkan/gstvkdescriptorcache.c
gst-libs/gst/vulkan/gstvkdescriptorcache.h
gst-libs/gst/vulkan/gstvkdescriptorpool.h
gst-libs/gst/vulkan/gstvkdescriptorset.c
gst-libs/gst/vulkan/gstvkdevice.c
gst-libs/gst/vulkan/gstvkdevice.h
gst-libs/gst/vulkan/gstvkfence.c
gst-libs/gst/vulkan/gstvkfence.h
gst-libs/gst/vulkan/gstvkhandlepool.c [new file with mode: 0644]
gst-libs/gst/vulkan/gstvkhandlepool.h [new file with mode: 0644]
gst-libs/gst/vulkan/gstvkswapper.c
gst-libs/gst/vulkan/gstvktrash.c
gst-libs/gst/vulkan/gstvktrash.h
gst-libs/gst/vulkan/meson.build
gst-libs/gst/vulkan/vulkan.h
gst-libs/gst/vulkan/vulkan_fwd.h
meson.build
meson_options.txt

index 0ff0e0d..9e14a8a 100644 (file)
@@ -1209,7 +1209,7 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
   VkResult err;
   int i;
 
-  fence = gst_vulkan_fence_new (vfilter->device, 0, &error);
+  fence = gst_vulkan_device_create_fence (vfilter->device, &error);
   if (!fence)
     goto error;
 
@@ -1226,7 +1226,8 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
     in_img_views[i] =
         get_or_create_image_view ((GstVulkanImageMemory *) img_mem);
     gst_vulkan_trash_list_add (conv->quad->trash_list,
-        gst_vulkan_trash_new_mini_object_unref (fence,
+        gst_vulkan_trash_list_acquire (conv->quad->trash_list, fence,
+            gst_vulkan_trash_mini_object_unref,
             (GstMiniObject *) in_img_views[i]));
   }
 
@@ -1280,7 +1281,8 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
             gst_memory_ref ((GstMemory *) render_img_mems[i]));
       }
       gst_vulkan_trash_list_add (conv->quad->trash_list,
-          gst_vulkan_trash_new_mini_object_unref (fence,
+          gst_vulkan_trash_list_acquire (conv->quad->trash_list, fence,
+              gst_vulkan_trash_mini_object_unref,
               (GstMiniObject *) render_buf));
     } else {
       render_buf = outbuf;
@@ -1296,7 +1298,8 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
       render_img_views[i] =
           get_or_create_image_view ((GstVulkanImageMemory *) img_mem);
       gst_vulkan_trash_list_add (conv->quad->trash_list,
-          gst_vulkan_trash_new_mini_object_unref (fence,
+          gst_vulkan_trash_list_acquire (conv->quad->trash_list, fence,
+              gst_vulkan_trash_mini_object_unref,
               (GstMiniObject *) render_img_views[i]));
     }
   }
@@ -1445,7 +1448,8 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
 
       /* XXX: try to reuse this image later */
       gst_vulkan_trash_list_add (conv->quad->trash_list,
-          gst_vulkan_trash_new_mini_object_unref (fence,
+          gst_vulkan_trash_list_acquire (conv->quad->trash_list, fence,
+              gst_vulkan_trash_mini_object_unref,
               (GstMiniObject *) render_img_mems[i]));
     }
   }
index 897cd1f..1bb64b8 100644 (file)
@@ -307,7 +307,7 @@ _image_to_raw_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
     };
     /* *INDENT-ON* */
 
-    fence = gst_vulkan_fence_new (raw->download->device, 0, &error);
+    fence = gst_vulkan_device_create_fence (raw->download->device, &error);
     if (!fence)
       goto error;
 
@@ -320,7 +320,8 @@ _image_to_raw_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
       goto error;
 
     gst_vulkan_trash_list_add (raw->trash_list,
-        gst_vulkan_trash_new_mini_object_unref (fence,
+        gst_vulkan_trash_list_acquire (raw->trash_list, fence,
+            gst_vulkan_trash_mini_object_unref,
             GST_MINI_OBJECT_CAST (cmd_buf)));
     gst_vulkan_fence_unref (fence);
   }
index 00f11c1..4f35c61 100644 (file)
@@ -627,7 +627,8 @@ clear_descriptor_set (GstVulkanFullScreenQuad * self)
 
   if (self->descriptor_set)
     gst_vulkan_trash_list_add (self->trash_list,
-        gst_vulkan_trash_new_mini_object_unref (last_fence,
+        gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+            gst_vulkan_trash_mini_object_unref,
             (GstMiniObject *) self->descriptor_set));
   self->descriptor_set = NULL;
 
@@ -642,7 +643,8 @@ clear_framebuffer (GstVulkanFullScreenQuad * self)
 
   if (self->framebuffer)
     gst_vulkan_trash_list_add (self->trash_list,
-        gst_vulkan_trash_new_mini_object_unref (last_fence,
+        gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+            gst_vulkan_trash_mini_object_unref,
             (GstMiniObject *) self->framebuffer));
   self->framebuffer = NULL;
 
@@ -657,8 +659,8 @@ clear_command_pool (GstVulkanFullScreenQuad * self)
 
   if (self->cmd_pool)
     gst_vulkan_trash_list_add (self->trash_list,
-        gst_vulkan_trash_new_object_unref (last_fence,
-            (GstObject *) self->cmd_pool));
+        gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+            gst_vulkan_trash_object_unref, (GstObject *) self->cmd_pool));
   self->cmd_pool = NULL;
 
   gst_vulkan_fence_unref (last_fence);
@@ -672,7 +674,8 @@ clear_sampler (GstVulkanFullScreenQuad * self)
 
   if (self->sampler)
     gst_vulkan_trash_list_add (self->trash_list,
-        gst_vulkan_trash_new_mini_object_unref (last_fence,
+        gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+            gst_vulkan_trash_mini_object_unref,
             (GstMiniObject *) self->sampler));
   self->sampler = NULL;
 
@@ -687,7 +690,8 @@ clear_descriptor_cache (GstVulkanFullScreenQuad * self)
 
   if (self->descriptor_cache)
     gst_vulkan_trash_list_add (self->trash_list,
-        gst_vulkan_trash_new_object_unref (last_fence,
+        gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+            gst_vulkan_trash_object_unref,
             (GstObject *) self->descriptor_cache));
   self->descriptor_cache = NULL;
 
@@ -703,14 +707,14 @@ clear_shaders (GstVulkanFullScreenQuad * self)
 
   if (priv->vert)
     gst_vulkan_trash_list_add (self->trash_list,
-        gst_vulkan_trash_new_mini_object_unref (last_fence,
-            (GstMiniObject *) priv->vert));
+        gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+            gst_vulkan_trash_mini_object_unref, (GstMiniObject *) priv->vert));
   priv->vert = NULL;
 
   if (priv->frag)
     gst_vulkan_trash_list_add (self->trash_list,
-        gst_vulkan_trash_new_mini_object_unref (last_fence,
-            (GstMiniObject *) priv->frag));
+        gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+            gst_vulkan_trash_mini_object_unref, (GstMiniObject *) priv->frag));
   priv->frag = NULL;
 
   gst_vulkan_fence_unref (last_fence);
@@ -725,7 +729,8 @@ clear_uniform_data (GstVulkanFullScreenQuad * self)
 
   if (priv->uniforms)
     gst_vulkan_trash_list_add (self->trash_list,
-        gst_vulkan_trash_new_mini_object_unref (last_fence,
+        gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+            gst_vulkan_trash_mini_object_unref,
             (GstMiniObject *) priv->uniforms));
   priv->uniforms = NULL;
   priv->uniform_size = 0;
@@ -741,22 +746,26 @@ destroy_pipeline (GstVulkanFullScreenQuad * self)
 
   if (self->render_pass)
     gst_vulkan_trash_list_add (self->trash_list,
-        gst_vulkan_trash_new_mini_object_unref (last_fence,
+        gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+            gst_vulkan_trash_mini_object_unref,
             (GstMiniObject *) self->render_pass));
   self->render_pass = NULL;
   if (self->pipeline_layout)
     gst_vulkan_trash_list_add (self->trash_list,
-        gst_vulkan_trash_new_mini_object_unref (last_fence,
+        gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+            gst_vulkan_trash_mini_object_unref,
             (GstMiniObject *) self->pipeline_layout));
   self->pipeline_layout = NULL;
   if (self->graphics_pipeline)
     gst_vulkan_trash_list_add (self->trash_list,
-        gst_vulkan_trash_new_mini_object_unref (last_fence,
+        gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+            gst_vulkan_trash_mini_object_unref,
             (GstMiniObject *) self->graphics_pipeline));
   self->graphics_pipeline = NULL;
   if (self->descriptor_set_layout)
     gst_vulkan_trash_list_add (self->trash_list,
-        gst_vulkan_trash_new_mini_object_unref (last_fence,
+        gst_vulkan_trash_list_acquire (self->trash_list, last_fence,
+            gst_vulkan_trash_mini_object_unref,
             (GstMiniObject *) self->descriptor_set_layout));
   self->descriptor_set_layout = NULL;
 
@@ -985,7 +994,7 @@ gst_vulkan_full_screen_quad_draw (GstVulkanFullScreenQuad * self,
 
   g_return_val_if_fail (GST_IS_VULKAN_FULL_SCREEN_QUAD (self), FALSE);
 
-  fence = gst_vulkan_fence_new (self->queue->device, 0, error);
+  fence = gst_vulkan_device_create_fence (self->queue->device, error);
   if (!fence)
     goto error;
 
@@ -1073,7 +1082,8 @@ gst_vulkan_full_screen_quad_prepare_draw (GstVulkanFullScreenQuad * self,
       }
       in_views[i] = get_or_create_image_view (img_mem);
       gst_vulkan_trash_list_add (self->trash_list,
-          gst_vulkan_trash_new_mini_object_unref (fence,
+          gst_vulkan_trash_list_acquire (self->trash_list, fence,
+              gst_vulkan_trash_mini_object_unref,
               (GstMiniObject *) in_views[i]));
     }
     if (!(self->descriptor_set =
@@ -1091,7 +1101,8 @@ gst_vulkan_full_screen_quad_prepare_draw (GstVulkanFullScreenQuad * self,
       }
       out_views[i] = get_or_create_image_view (img_mem);
       gst_vulkan_trash_list_add (self->trash_list,
-          gst_vulkan_trash_new_mini_object_unref (fence,
+          gst_vulkan_trash_list_acquire (self->trash_list, fence,
+              gst_vulkan_trash_mini_object_unref,
               (GstMiniObject *) out_views[i]));
     }
     if (!create_framebuffer (self, out_views, error))
@@ -1145,8 +1156,8 @@ gst_vulkan_full_screen_quad_fill_command_buffer (GstVulkanFullScreenQuad * self,
     }
     in_views[i] = get_or_create_image_view (img_mem);
     gst_vulkan_trash_list_add (self->trash_list,
-        gst_vulkan_trash_new_mini_object_unref (fence,
-            (GstMiniObject *) in_views[i]));
+        gst_vulkan_trash_list_acquire (self->trash_list, fence,
+            gst_vulkan_trash_mini_object_unref, (GstMiniObject *) in_views[i]));
   }
   for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&self->out_info); i++) {
     GstVulkanImageMemory *img_mem = peek_image_from_buffer (priv->outbuf, i);
@@ -1157,7 +1168,8 @@ gst_vulkan_full_screen_quad_fill_command_buffer (GstVulkanFullScreenQuad * self,
     }
     out_views[i] = get_or_create_image_view (img_mem);
     gst_vulkan_trash_list_add (self->trash_list,
-        gst_vulkan_trash_new_mini_object_unref (fence,
+        gst_vulkan_trash_list_acquire (self->trash_list, fence,
+            gst_vulkan_trash_mini_object_unref,
             (GstMiniObject *) out_views[i]));
   }
 
@@ -1309,8 +1321,8 @@ gst_vulkan_full_screen_quad_submit (GstVulkanFullScreenQuad * self,
   }
 
   gst_vulkan_trash_list_add (self->trash_list,
-      gst_vulkan_trash_new_mini_object_unref (fence,
-          GST_MINI_OBJECT_CAST (cmd)));
+      gst_vulkan_trash_list_acquire (self->trash_list, fence,
+          gst_vulkan_trash_mini_object_unref, GST_MINI_OBJECT_CAST (cmd)));
 
   gst_vulkan_trash_list_gc (self->trash_list);
 
index 7edf64d..0f2a6e9 100644 (file)
@@ -599,7 +599,7 @@ _buffer_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
     };
     /* *INDENT-ON* */
 
-    fence = gst_vulkan_fence_new (raw->upload->device, 0, &error);
+    fence = gst_vulkan_device_create_fence (raw->upload->device, &error);
     if (!fence)
       goto error;
 
@@ -610,7 +610,8 @@ _buffer_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
       goto error;
 
     gst_vulkan_trash_list_add (raw->trash_list,
-        gst_vulkan_trash_new_mini_object_unref (fence,
+        gst_vulkan_trash_list_acquire (raw->trash_list, fence,
+            gst_vulkan_trash_mini_object_unref,
             GST_MINI_OBJECT_CAST (cmd_buf)));
     gst_vulkan_fence_unref (fence);
   }
@@ -983,7 +984,7 @@ _raw_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
     };
     /* *INDENT-ON* */
 
-    fence = gst_vulkan_fence_new (raw->upload->device, 0, &error);
+    fence = gst_vulkan_device_create_fence (raw->upload->device, &error);
     if (!fence)
       goto error;
 
@@ -996,7 +997,8 @@ _raw_to_image_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf)
       goto error;
 
     gst_vulkan_trash_list_add (raw->trash_list,
-        gst_vulkan_trash_new_mini_object_unref (fence,
+        gst_vulkan_trash_list_acquire (raw->trash_list, fence,
+            gst_vulkan_trash_mini_object_unref,
             GST_MINI_OBJECT_CAST (cmd_buf)));
     gst_vulkan_fence_unref (fence);
   }
index 8f58325..c37b6d2 100644 (file)
@@ -1915,7 +1915,7 @@ gst_vulkan_view_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
           &error))
     goto error;
 
-  fence = gst_vulkan_fence_new (vfilter->device, 0, &error);
+  fence = gst_vulkan_device_create_fence (vfilter->device, &error);
   if (!fence)
     goto error;
 
@@ -1929,7 +1929,8 @@ gst_vulkan_view_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
     in_img_views[i] =
         get_or_create_image_view ((GstVulkanImageMemory *) img_mem);
     gst_vulkan_trash_list_add (conv->quad->trash_list,
-        gst_vulkan_trash_new_mini_object_unref (fence,
+        gst_vulkan_trash_list_acquire (conv->quad->trash_list, fence,
+            gst_vulkan_trash_mini_object_unref,
             (GstMiniObject *) in_img_views[i]));
   }
   for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&conv->quad->out_info); i++) {
@@ -1941,7 +1942,8 @@ gst_vulkan_view_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
     }
     out_img_views[i] = get_or_create_image_view ((GstVulkanImageMemory *) mem);
     gst_vulkan_trash_list_add (conv->quad->trash_list,
-        gst_vulkan_trash_new_mini_object_unref (fence,
+        gst_vulkan_trash_list_acquire (conv->quad->trash_list, fence,
+            gst_vulkan_trash_mini_object_unref,
             (GstMiniObject *) out_img_views[i]));
   }
 
diff --git a/gst-libs/gst/vulkan/gstvkdescriptorcache-private.h b/gst-libs/gst/vulkan/gstvkdescriptorcache-private.h
deleted file mode 100644 (file)
index 9c0d50b..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2019 Matthew Waters <matthew@centricular.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef __GST_VULKAN_DESCRIPTOR_CACHE_PRIVATE_H__
-#define __GST_VULKAN_DESCRIPTOR_CACHE_PRIVATE_H__
-
-#include <gst/gst.h>
-
-G_BEGIN_DECLS
-
-void        gst_vulkan_descriptor_cache_release_set     (GstVulkanDescriptorCache * cache,
-                                                         GstVulkanDescriptorSet * set);
-
-G_END_DECLS
-
-#endif /* __GST_VULKAN_COMMAND_POOL_PRIVATE_H__ */
index a2dff8a..c90156f 100644 (file)
@@ -23,7 +23,6 @@
 #endif
 
 #include "gstvkdescriptorcache.h"
-#include "gstvkdescriptorcache-private.h"
 
 /**
  * SECTION:vkdescriptorcache
@@ -41,42 +40,14 @@ struct _GstVulkanDescriptorCachePrivate
 {
   guint n_layouts;
   GstVulkanHandle **layouts;
-
-  GQueue *available;
-  gsize outstanding;
 };
 
 #define parent_class gst_vulkan_descriptor_cache_parent_class
 G_DEFINE_TYPE_WITH_CODE (GstVulkanDescriptorCache, gst_vulkan_descriptor_cache,
-    GST_TYPE_OBJECT, G_ADD_PRIVATE (GstVulkanDescriptorCache);
+    GST_TYPE_VULKAN_HANDLE_POOL, G_ADD_PRIVATE (GstVulkanDescriptorCache);
     GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT,
         "vulkancommandcache", 0, "Vulkan Command Cache"));
 
-static void gst_vulkan_descriptor_cache_finalize (GObject * object);
-
-static void
-gst_vulkan_descriptor_cache_init (GstVulkanDescriptorCache * cache)
-{
-  GstVulkanDescriptorCachePrivate *priv = GET_PRIV (cache);
-
-  priv->available = g_queue_new ();
-}
-
-static void
-gst_vulkan_descriptor_cache_class_init (GstVulkanDescriptorCacheClass *
-    device_class)
-{
-  GObjectClass *gobject_class = (GObjectClass *) device_class;
-
-  gobject_class->finalize = gst_vulkan_descriptor_cache_finalize;
-}
-
-static void
-do_free_set (GstVulkanHandle * handle)
-{
-  gst_vulkan_handle_unref (handle);
-}
-
 static void
 gst_vulkan_descriptor_cache_finalize (GObject * object)
 {
@@ -84,17 +55,10 @@ gst_vulkan_descriptor_cache_finalize (GObject * object)
   GstVulkanDescriptorCachePrivate *priv = GET_PRIV (cache);
   guint i;
 
-  if (priv->outstanding > 0)
-    g_critical
-        ("Destroying a Vulkan descriptor cache that has outstanding descriptors!");
-
   for (i = 0; i < priv->n_layouts; i++)
     gst_vulkan_handle_unref (priv->layouts[i]);
   g_free (priv->layouts);
 
-  g_queue_free_full (priv->available, (GDestroyNotify) do_free_set);
-  priv->available = NULL;
-
   gst_clear_object (&cache->pool);
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -114,6 +78,7 @@ GstVulkanDescriptorCache *
 gst_vulkan_descriptor_cache_new (GstVulkanDescriptorPool * pool,
     guint n_layouts, GstVulkanHandle ** layouts)
 {
+  GstVulkanHandlePool *handle_pool;
   GstVulkanDescriptorCache *ret;
   GstVulkanDescriptorCachePrivate *priv;
   guint i;
@@ -129,11 +94,61 @@ gst_vulkan_descriptor_cache_new (GstVulkanDescriptorPool * pool,
   for (i = 0; i < n_layouts; i++)
     priv->layouts[i] = gst_vulkan_handle_ref (layouts[i]);
 
+  handle_pool = GST_VULKAN_HANDLE_POOL (ret);
+  handle_pool->device = gst_object_ref (pool->device);
+
   gst_object_ref_sink (ret);
 
   return ret;
 }
 
+static gpointer
+gst_vulkan_descriptor_cache_acquire_impl (GstVulkanHandlePool * pool,
+    GError ** error)
+{
+  GstVulkanDescriptorSet *set;
+
+  if ((set =
+          GST_VULKAN_HANDLE_POOL_CLASS (parent_class)->acquire (pool, error)))
+    set->cache = gst_object_ref (pool);
+
+  return set;
+}
+
+static gpointer
+gst_vulkan_descriptor_cache_alloc_impl (GstVulkanHandlePool * pool,
+    GError ** error)
+{
+  GstVulkanDescriptorCache *desc = GST_VULKAN_DESCRIPTOR_CACHE (pool);
+  GstVulkanDescriptorCachePrivate *priv = GET_PRIV (desc);
+
+  return gst_vulkan_descriptor_pool_create (desc->pool, priv->n_layouts,
+      priv->layouts, error);
+}
+
+static void
+gst_vulkan_descriptor_cache_release_impl (GstVulkanHandlePool * pool,
+    gpointer handle)
+{
+  GstVulkanDescriptorSet *set = handle;
+
+  GST_VULKAN_HANDLE_POOL_CLASS (parent_class)->release (pool, handle);
+
+  /* decrease the refcount that the set had to us */
+  gst_clear_object (&set->cache);
+}
+
+static void
+gst_vulkan_descriptor_cache_free_impl (GstVulkanHandlePool * pool,
+    gpointer handle)
+{
+  GstVulkanDescriptorSet *set = handle;
+
+  GST_VULKAN_HANDLE_POOL_CLASS (parent_class)->free (pool, handle);
+
+  gst_vulkan_descriptor_set_unref (set);
+}
+
 /**
  * gst_vulkan_descriptor_cache_acquire:
  * @cache: a #GstVulkanDescriptorCache
@@ -147,47 +162,25 @@ GstVulkanDescriptorSet *
 gst_vulkan_descriptor_cache_acquire (GstVulkanDescriptorCache * cache,
     GError ** error)
 {
-  GstVulkanDescriptorSet *set = NULL;
-  GstVulkanDescriptorCachePrivate *priv;
-
-  g_return_val_if_fail (GST_IS_VULKAN_DESCRIPTOR_CACHE (cache), NULL);
-
-  priv = GET_PRIV (cache);
-
-  GST_OBJECT_LOCK (cache);
-  set = g_queue_pop_head (priv->available);
-  GST_OBJECT_UNLOCK (cache);
-
-  if (!set)
-    set = gst_vulkan_descriptor_pool_create (cache->pool, priv->n_layouts,
-        priv->layouts, error);
-  if (!set)
-    return NULL;
-
-  GST_OBJECT_LOCK (cache);
-  priv->outstanding++;
-  GST_OBJECT_UNLOCK (cache);
-
-  set->cache = gst_object_ref (cache);
-  return set;
+  return gst_vulkan_handle_pool_acquire (GST_VULKAN_HANDLE_POOL_CAST (cache),
+      error);
 }
 
-void
-gst_vulkan_descriptor_cache_release_set (GstVulkanDescriptorCache * cache,
-    GstVulkanDescriptorSet * set)
+static void
+gst_vulkan_descriptor_cache_init (GstVulkanDescriptorCache * cache)
 {
-  GstVulkanDescriptorCachePrivate *priv;
-
-  g_return_if_fail (GST_IS_VULKAN_DESCRIPTOR_CACHE (cache));
-  g_return_if_fail (set != NULL);
+}
 
-  priv = GET_PRIV (cache);
+static void
+gst_vulkan_descriptor_cache_class_init (GstVulkanDescriptorCacheClass * klass)
+{
+  GObjectClass *gobject_class = (GObjectClass *) klass;
+  GstVulkanHandlePoolClass *handle_class = (GstVulkanHandlePoolClass *) klass;
 
-  GST_OBJECT_LOCK (cache);
-  g_queue_push_tail (priv->available, set);
-  priv->outstanding--;
-  GST_OBJECT_UNLOCK (cache);
+  gobject_class->finalize = gst_vulkan_descriptor_cache_finalize;
 
-  /* decrease the refcount that the set had to us */
-  gst_clear_object (&set->cache);
+  handle_class->acquire = gst_vulkan_descriptor_cache_acquire_impl;
+  handle_class->alloc = gst_vulkan_descriptor_cache_alloc_impl;
+  handle_class->release = gst_vulkan_descriptor_cache_release_impl;
+  handle_class->free = gst_vulkan_descriptor_cache_free_impl;
 }
index 02d9a67..b6e9bfc 100644 (file)
@@ -22,6 +22,7 @@
 #define __GST_VULKAN_DESCRIPTOR_CACHE_H__
 
 #include <gst/vulkan/gstvkqueue.h>
+#include <gst/vulkan/gstvkhandlepool.h>
 
 #define GST_TYPE_VULKAN_DESCRIPTOR_CACHE         (gst_vulkan_descriptor_cache_get_type())
 #define GST_VULKAN_DESCRIPTOR_CACHE(o)           (G_TYPE_CHECK_INSTANCE_CAST((o), GST_TYPE_VULKAN_DESCRIPTOR_CACHE, GstVulkanDescriptorCache))
@@ -34,14 +35,14 @@ GType gst_vulkan_descriptor_cache_get_type       (void);
 
 struct _GstVulkanDescriptorCache
 {
-  GstObject                     parent;
+  GstVulkanHandlePool           parent;
 
   GstVulkanDescriptorPool      *pool;
 };
 
 struct _GstVulkanDescriptorCacheClass
 {
-  GstObjectClass parent_class;
+  GstVulkanHandlePoolClass      parent_class;
 };
 
 GST_VULKAN_API
index b2e6840..868a7e1 100644 (file)
 
 #include <gst/vulkan/gstvkqueue.h>
 
+GST_VULKAN_API
+GType gst_vulkan_descriptor_pool_get_type       (void);
 #define GST_TYPE_VULKAN_DESCRIPTOR_POOL         (gst_vulkan_descriptor_pool_get_type())
 #define GST_VULKAN_DESCRIPTOR_POOL(o)           (G_TYPE_CHECK_INSTANCE_CAST((o), GST_TYPE_VULKAN_DESCRIPTOR_POOL, GstVulkanDescriptorPool))
 #define GST_VULKAN_DESCRIPTOR_POOL_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GST_TYPE_VULKAN_DESCRIPTOR_POOL, GstVulkanDescriptorPoolClass))
 #define GST_IS_VULKAN_DESCRIPTOR_POOL(o)        (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_TYPE_VULKAN_DESCRIPTOR_POOL))
 #define GST_IS_VULKAN_DESCRIPTOR_POOL_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE((k), GST_TYPE_VULKAN_DESCRIPTOR_POOL))
 #define GST_VULKAN_DESCRIPTOR_POOL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_TYPE_VULKAN_DESCRIPTOR_POOL, GstVulkanDescriptorPoolClass))
-GST_VULKAN_API
-GType gst_vulkan_descriptor_pool_get_type       (void);
 
 struct _GstVulkanDescriptorPool
 {
index a2adacc..7b33577 100644 (file)
 #include "gstvkdescriptorset.h"
 #include "gstvkdescriptorpool.h"
 #include "gstvkdescriptorcache.h"
-#include "gstvkdescriptorcache-private.h"
 
 #define GST_CAT_DEFAULT gst_debug_vulkan_descriptor_set
 GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
 
+#define gst_vulkan_descriptor_cache_release_set(c,s) \
+    gst_vulkan_handle_pool_release (GST_VULKAN_HANDLE_POOL_CAST (c), s);
+
 static void
 init_debug (void)
 {
index b712162..dd6c345 100644 (file)
@@ -49,6 +49,7 @@ enum
   PROP_PHYSICAL_DEVICE,
 };
 
+static void gst_vulkan_device_dispose (GObject * object);
 static void gst_vulkan_device_finalize (GObject * object);
 
 struct _GstVulkanDevicePrivate
@@ -56,6 +57,8 @@ struct _GstVulkanDevicePrivate
   gboolean opened;
   guint queue_family_id;
   guint n_queues;
+
+  GstVulkanFenceCache *fence_cache;
 };
 
 static void
@@ -168,6 +171,8 @@ gst_vulkan_device_constructed (GObject * object)
   GstVulkanDevice *device = GST_VULKAN_DEVICE (object);
 
   g_object_get (device->physical_device, "instance", &device->instance, NULL);
+
+  G_OBJECT_CLASS (parent_class)->constructed (object);
 }
 
 static void
@@ -178,6 +183,7 @@ gst_vulkan_device_class_init (GstVulkanDeviceClass * device_class)
   gobject_class->set_property = gst_vulkan_device_set_property;
   gobject_class->get_property = gst_vulkan_device_get_property;
   gobject_class->finalize = gst_vulkan_device_finalize;
+  gobject_class->dispose = gst_vulkan_device_dispose;
   gobject_class->constructed = gst_vulkan_device_constructed;
 
   g_object_class_install_property (gobject_class, PROP_INSTANCE,
@@ -192,6 +198,24 @@ gst_vulkan_device_class_init (GstVulkanDeviceClass * device_class)
 }
 
 static void
+gst_vulkan_device_dispose (GObject * object)
+{
+  GstVulkanDevice *device = GST_VULKAN_DEVICE (object);
+  GstVulkanDevicePrivate *priv = GET_PRIV (device);
+
+  if (priv->fence_cache) {
+    /* clear any outstanding fences */
+    g_object_run_dispose (G_OBJECT (priv->fence_cache));
+
+    /* don't double free this device */
+    priv->fence_cache->parent.device = NULL;
+  }
+  gst_clear_object (&priv->fence_cache);
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
 gst_vulkan_device_finalize (GObject * object)
 {
   GstVulkanDevice *device = GST_VULKAN_DEVICE (object);
@@ -305,6 +329,10 @@ gst_vulkan_device_open (GstVulkanDevice * device, GError ** error)
     }
   }
 
+  priv->fence_cache = gst_vulkan_fence_cache_new (device);
+  /* avoid reference loops between us and the fence cache */
+  gst_object_unref (device);
+
   priv->opened = TRUE;
   GST_OBJECT_UNLOCK (device);
   return TRUE;
@@ -590,3 +618,14 @@ gst_vulkan_device_run_context_query (GstElement * element,
 
   return FALSE;
 }
+
+GstVulkanFence *
+gst_vulkan_device_create_fence (GstVulkanDevice * device, GError ** error)
+{
+  GstVulkanDevicePrivate *priv;
+
+  g_return_val_if_fail (GST_IS_VULKAN_DEVICE (device), NULL);
+  priv = GET_PRIV (device);
+
+  return gst_vulkan_fence_cache_acquire (priv->fence_cache, error);
+}
index 567b287..1614f98 100644 (file)
@@ -91,6 +91,10 @@ GST_VULKAN_API
 gboolean            gst_vulkan_device_run_context_query     (GstElement * element,
                                                              GstVulkanDevice ** device);
 
+GST_VULKAN_API
+GstVulkanFence *    gst_vulkan_device_create_fence          (GstVulkanDevice * device,
+                                                             GError ** error);
+
 G_END_DECLS
 
 #endif /* __GST_VULKAN_DEVICE_H__ */
index 8e4ffaf..a624b9b 100644 (file)
@@ -23,6 +23,7 @@
 #endif
 
 #include "gstvkfence.h"
+#include "gstvkdevice.h"
 
 /**
  * SECTION:vkfence
@@ -36,6 +37,8 @@
 GST_DEBUG_CATEGORY (gst_debug_vulkan_fence);
 #define GST_CAT_DEFAULT gst_debug_vulkan_fence
 
+#define gst_vulkan_fence_cache_release(c,f) gst_vulkan_handle_pool_release(GST_VULKAN_HANDLE_POOL (c), f)
+
 static void
 _init_debug (void)
 {
@@ -48,6 +51,23 @@ _init_debug (void)
   }
 }
 
+static gboolean
+gst_vulkan_fence_dispose (GstVulkanFence * fence)
+{
+  GstVulkanFenceCache *cache;
+
+  /* no pool, do free */
+  if ((cache = fence->cache) == NULL)
+    return TRUE;
+
+  /* keep the buffer alive */
+  gst_vulkan_fence_ref (fence);
+  /* return the buffer to the cache */
+  gst_vulkan_fence_cache_release (cache, fence);
+
+  return FALSE;
+}
+
 static void
 gst_vulkan_fence_free (GstVulkanFence * fence)
 {
@@ -59,7 +79,7 @@ gst_vulkan_fence_free (GstVulkanFence * fence)
   if (fence->fence)
     vkDestroyFence (fence->device->device, fence->fence, NULL);
 
-  gst_object_unref (fence->device);
+  gst_clear_object (&fence->device);
 
   g_free (fence);
 }
@@ -67,7 +87,6 @@ gst_vulkan_fence_free (GstVulkanFence * fence)
 /**
  * gst_vulkan_fence_new:
  * @device: the parent #GstVulkanDevice
- * @flags: set of flags to create the fence with
  * @error: a #GError for the failure condition
  *
  * Returns: whether a new #GstVulkanFence or %NULL on error
@@ -75,8 +94,7 @@ gst_vulkan_fence_free (GstVulkanFence * fence)
  * Since: 1.18
  */
 GstVulkanFence *
-gst_vulkan_fence_new (GstVulkanDevice * device, VkFenceCreateFlags flags,
-    GError ** error)
+gst_vulkan_fence_new (GstVulkanDevice * device, GError ** error)
 {
   VkFenceCreateInfo fence_info = { 0, };
   GstVulkanFence *fence;
@@ -92,7 +110,7 @@ gst_vulkan_fence_new (GstVulkanDevice * device, VkFenceCreateFlags flags,
 
   fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
   fence_info.pNext = NULL;
-  fence_info.flags = flags;
+  fence_info.flags = 0;
 
   err = vkCreateFence (device->device, &fence_info, NULL, &fence->fence);
   if (gst_vulkan_error_to_g_error (err, error, "vkCreateFence") < 0) {
@@ -102,7 +120,8 @@ gst_vulkan_fence_new (GstVulkanDevice * device, VkFenceCreateFlags flags,
   }
 
   gst_mini_object_init (GST_MINI_OBJECT_CAST (fence), 0, GST_TYPE_VULKAN_FENCE,
-      NULL, NULL, (GstMiniObjectFreeFunction) gst_vulkan_fence_free);
+      NULL, (GstMiniObjectDisposeFunction) gst_vulkan_fence_dispose,
+      (GstMiniObjectFreeFunction) gst_vulkan_fence_free);
 
   return fence;
 }
@@ -152,4 +171,103 @@ gst_vulkan_fence_is_signaled (GstVulkanFence * fence)
   return vkGetFenceStatus (fence->device->device, fence->fence) == VK_SUCCESS;
 }
 
+void
+gst_vulkan_fence_reset (GstVulkanFence * fence)
+{
+  g_return_if_fail (fence != NULL);
+
+  if (!fence->fence)
+    return;
+
+  GST_TRACE ("resetting fence %p", fence);
+  vkResetFences (fence->device->device, 1, &fence->fence);
+}
+
 GST_DEFINE_MINI_OBJECT_TYPE (GstVulkanFence, gst_vulkan_fence);
+
+#define parent_class gst_vulkan_fence_cache_parent_class
+G_DEFINE_TYPE_WITH_CODE (GstVulkanFenceCache, gst_vulkan_fence_cache,
+    GST_TYPE_VULKAN_HANDLE_POOL, _init_debug ());
+
+GstVulkanFenceCache *
+gst_vulkan_fence_cache_new (GstVulkanDevice * device)
+{
+  GstVulkanFenceCache *ret;
+  GstVulkanHandlePool *pool;
+
+  g_return_val_if_fail (GST_IS_VULKAN_DEVICE (device), NULL);
+
+  ret = g_object_new (GST_TYPE_VULKAN_FENCE_CACHE, NULL);
+
+  pool = GST_VULKAN_HANDLE_POOL (ret);
+  pool->device = gst_object_ref (device);
+
+  gst_object_ref_sink (ret);
+
+  return ret;
+}
+
+static gpointer
+gst_vulkan_fence_cache_alloc (GstVulkanHandlePool * pool, GError ** error)
+{
+  return gst_vulkan_fence_new (pool->device, error);
+}
+
+static gpointer
+gst_vulkan_fence_cache_acquire_impl (GstVulkanHandlePool * pool,
+    GError ** error)
+{
+  GstVulkanFence *fence;
+
+  if ((fence =
+          GST_VULKAN_HANDLE_POOL_CLASS (parent_class)->acquire (pool, error))) {
+    fence->cache = gst_object_ref (pool);
+    if (!fence->device)
+      fence->device = gst_object_ref (pool->device);
+  }
+
+  return fence;
+}
+
+static void
+gst_vulkan_fence_cache_release_impl (GstVulkanHandlePool * pool,
+    gpointer handle)
+{
+  GstVulkanFence *fence = handle;
+
+  gst_vulkan_fence_reset (fence);
+
+  GST_VULKAN_HANDLE_POOL_CLASS (parent_class)->release (pool, handle);
+
+  if (fence) {
+    gst_clear_object (&fence->cache);
+    gst_clear_object (&fence->device);
+  }
+}
+
+static void
+gst_vulkan_fence_cache_free (GstVulkanHandlePool * pool, gpointer handle)
+{
+  GstVulkanFence *fence = handle;
+
+  if (!fence->device)
+    fence->device = gst_object_ref (pool->device);
+
+  gst_vulkan_fence_unref (handle);
+}
+
+static void
+gst_vulkan_fence_cache_init (GstVulkanFenceCache * cache)
+{
+}
+
+static void
+gst_vulkan_fence_cache_class_init (GstVulkanFenceCacheClass * klass)
+{
+  GstVulkanHandlePoolClass *handle_class = (GstVulkanHandlePoolClass *) klass;
+
+  handle_class->acquire = gst_vulkan_fence_cache_acquire_impl;
+  handle_class->alloc = gst_vulkan_fence_cache_alloc;
+  handle_class->release = gst_vulkan_fence_cache_release_impl;
+  handle_class->free = gst_vulkan_fence_cache_free;
+}
index a395bf6..069eb1d 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef __GST_VULKAN_FENCE_H__
 #define __GST_VULKAN_FENCE_H__
 
-#include <gst/vulkan/vulkan.h>
+#include <gst/vulkan/gstvkhandlepool.h>
 
 G_BEGIN_DECLS
 
@@ -37,15 +37,18 @@ struct _GstVulkanFence
   GstMiniObject parent;
 
   GstVulkanDevice *device;
+  GstVulkanFenceCache *cache;
 
   VkFence fence;
 };
 
 GST_VULKAN_API
 GstVulkanFence *    gst_vulkan_fence_new            (GstVulkanDevice * device,
-                                                     VkFenceCreateFlags flags,
                                                      GError ** error);
 GST_VULKAN_API
+void                gst_vulkan_fence_reset          (GstVulkanFence * fence);
+
+GST_VULKAN_API
 GstVulkanFence *    gst_vulkan_fence_new_always_signalled (GstVulkanDevice *device);
 
 GST_VULKAN_API
@@ -63,6 +66,32 @@ gst_vulkan_fence_unref (GstVulkanFence * fence)
   gst_mini_object_unref (GST_MINI_OBJECT_CAST (fence));
 }
 
+GST_VULKAN_API
+GType gst_vulkan_fence_cache_get_type       (void);
+#define GST_TYPE_VULKAN_FENCE_CACHE         (gst_vulkan_fence_cache_get_type())
+#define GST_VULKAN_FENCE_CACHE(o)           (G_TYPE_CHECK_INSTANCE_CAST((o), GST_TYPE_VULKAN_FENCE_CACHE, GstVulkanFenceCache))
+#define GST_VULKAN_FENCE_CACHE_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GST_TYPE_VULKAN_FENCE_CACHE, GstVulkanFenceCacheClass))
+#define GST_IS_VULKAN_FENCE_CACHE(o)        (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_TYPE_VULKAN_FENCE_CACHE))
+#define GST_IS_VULKAN_FENCE_CACHE_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE((k), GST_TYPE_VULKAN_FENCE_CACHE))
+#define GST_VULKAN_FENCE_CACHE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_TYPE_VULKAN_FENCE_CACHE, GstVulkanFenceCacheClass))
+
+struct _GstVulkanFenceCache
+{
+  GstVulkanHandlePool       parent;
+
+  /* <private> */
+  gpointer _reserved        [GST_PADDING];
+};
+
+struct _GstVulkanFenceCacheClass
+{
+  GstVulkanHandlePoolClass  parent_class;
+};
+
+GstVulkanFenceCache *       gst_vulkan_fence_cache_new         (GstVulkanDevice * device);
+
+#define gst_vulkan_fence_cache_acquire(o,e) (GstVulkanFence *) gst_vulkan_handle_pool_acquire (GST_VULKAN_HANDLE_POOL (o),e);
+
 G_END_DECLS
 
 #endif /* __GST_VULKAN_FENCE_H__ */
diff --git a/gst-libs/gst/vulkan/gstvkhandlepool.c b/gst-libs/gst/vulkan/gstvkhandlepool.c
new file mode 100644 (file)
index 0000000..22cc975
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * GStreamer
+ * Copyright (C) 2019 Matthew Waters <matthew@centricular.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * SECTION:vulkanhandlepool
+ * @title: vulkanhandlepool
+ *
+ * #GstVulkanHandlePool holds a number of handles that are pooled together.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gstvkhandlepool.h"
+#include "gstvkdevice.h"
+
+#define GST_VULKAN_HANDLE_POOL_LARGE_OUTSTANDING 1024
+
+#define GST_CAT_DEFAULT gst_debug_vulkan_handle_pool
+GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
+
+#define parent_class gst_vulkan_handle_pool_parent_class
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstVulkanHandlePool, gst_vulkan_handle_pool,
+    GST_TYPE_OBJECT, GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT,
+        "vulkanhandlepool", 0, "Vulkan handle pool"));
+
+static gpointer
+gst_vulkan_handle_pool_default_alloc (GstVulkanHandlePool * pool,
+    GError ** error)
+{
+  return NULL;
+}
+
+static gpointer
+gst_vulkan_handle_pool_default_acquire (GstVulkanHandlePool * pool,
+    GError ** error)
+{
+  gpointer ret;
+
+  GST_OBJECT_LOCK (pool);
+  if (pool->available->len > 0) {
+    ret = g_ptr_array_remove_index_fast (pool->available, 0);
+  } else {
+    ret = gst_vulkan_handle_pool_alloc (pool, error);
+  }
+
+  if (ret) {
+    g_ptr_array_add (pool->outstanding, ret);
+
+#if defined(GST_ENABLE_EXTRA_CHECKS)
+    if (pool->outstanding->len > GST_VULKAN_HANDLE_POOL_LARGE_OUTSTANDING)
+      g_critical ("%s: There are a large number of handles outstanding! "
+          "This usually means there is a reference counting issue somewhere.",
+          GST_OBJECT_NAME (pool));
+#endif
+  }
+  GST_OBJECT_UNLOCK (pool);
+
+  return ret;
+}
+
+static void
+gst_vulkan_handle_pool_default_release (GstVulkanHandlePool * pool,
+    gpointer handle)
+{
+  GST_OBJECT_LOCK (pool);
+  if (!g_ptr_array_remove_fast (pool->outstanding, handle)) {
+    g_warning ("%s: Attempt was made to release a handle (%p) that does not "
+        "belong to us", GST_OBJECT_NAME (pool), handle);
+    GST_OBJECT_UNLOCK (pool);
+    return;
+  }
+
+  g_ptr_array_add (pool->available, handle);
+  GST_OBJECT_UNLOCK (pool);
+}
+
+static void
+gst_vulkan_handle_pool_default_free (GstVulkanHandlePool * pool,
+    gpointer handle)
+{
+}
+
+static void
+do_free_handle (gpointer handle, GstVulkanHandlePool * pool)
+{
+  GstVulkanHandlePoolClass *klass = GST_VULKAN_HANDLE_POOL_GET_CLASS (pool);
+  klass->free (pool, handle);
+}
+
+static void
+gst_vulkan_handle_pool_dispose (GObject * object)
+{
+  GstVulkanHandlePool *pool = GST_VULKAN_HANDLE_POOL (object);
+
+  if (pool->outstanding) {
+    g_warn_if_fail (pool->outstanding->len <= 0);
+    g_ptr_array_unref (pool->outstanding);
+  }
+  pool->outstanding = NULL;
+
+  if (pool->available) {
+    g_ptr_array_foreach (pool->available, (GFunc) do_free_handle, pool);
+    g_ptr_array_unref (pool->available);
+  }
+  pool->available = NULL;
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gst_vulkan_handle_pool_finalize (GObject * object)
+{
+  GstVulkanHandlePool *pool = GST_VULKAN_HANDLE_POOL (object);
+
+  gst_clear_object (&pool->device);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gst_vulkan_handle_pool_init (GstVulkanHandlePool * handle)
+{
+  handle->outstanding = g_ptr_array_new ();
+  handle->available = g_ptr_array_new ();
+}
+
+static void
+gst_vulkan_handle_pool_class_init (GstVulkanHandlePoolClass * klass)
+{
+  GObjectClass *gobject_class = (GObjectClass *) klass;
+
+  gobject_class->dispose = gst_vulkan_handle_pool_dispose;
+  gobject_class->finalize = gst_vulkan_handle_pool_finalize;
+
+  klass->alloc = gst_vulkan_handle_pool_default_alloc;
+  klass->acquire = gst_vulkan_handle_pool_default_acquire;
+  klass->release = gst_vulkan_handle_pool_default_release;
+  klass->free = gst_vulkan_handle_pool_default_free;
+}
+
+gpointer
+gst_vulkan_handle_pool_alloc (GstVulkanHandlePool * pool, GError ** error)
+{
+  GstVulkanHandlePoolClass *klass;
+
+  g_return_val_if_fail (GST_IS_VULKAN_HANDLE_POOL (pool), NULL);
+  klass = GST_VULKAN_HANDLE_POOL_GET_CLASS (pool);
+  g_return_val_if_fail (klass->alloc != NULL, NULL);
+
+  return klass->alloc (pool, error);
+}
+
+gpointer
+gst_vulkan_handle_pool_acquire (GstVulkanHandlePool * pool, GError ** error)
+{
+  GstVulkanHandlePoolClass *klass;
+
+  g_return_val_if_fail (GST_IS_VULKAN_HANDLE_POOL (pool), NULL);
+  klass = GST_VULKAN_HANDLE_POOL_GET_CLASS (pool);
+  g_return_val_if_fail (klass->acquire != NULL, NULL);
+
+  return klass->acquire (pool, error);
+}
+
+void
+gst_vulkan_handle_pool_release (GstVulkanHandlePool * pool, gpointer handle)
+{
+  GstVulkanHandlePoolClass *klass;
+
+  g_return_if_fail (GST_IS_VULKAN_HANDLE_POOL (pool));
+  klass = GST_VULKAN_HANDLE_POOL_GET_CLASS (pool);
+  g_return_if_fail (klass->release != NULL);
+
+  klass->release (pool, handle);
+}
diff --git a/gst-libs/gst/vulkan/gstvkhandlepool.h b/gst-libs/gst/vulkan/gstvkhandlepool.h
new file mode 100644 (file)
index 0000000..a3acde3
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * GStreamer
+ * Copyright (C) 2019 Matthew Waters <matthew@centricular.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_VULKAN_HANDLE_POOL_H__
+#define __GST_VULKAN_HANDLE_POOL_H__
+
+#include <gst/gst.h>
+
+#include <gst/vulkan/vulkan_fwd.h>
+#include <gst/vulkan/gstvkapi.h>
+
+G_BEGIN_DECLS
+
+GST_VULKAN_API
+GType gst_vulkan_handle_pool_get_type (void);
+#define GST_TYPE_VULKAN_HANDLE_POOL            (gst_vulkan_handle_pool_get_type())
+#define GST_VULKAN_HANDLE_POOL(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VULKAN_HANDLE_POOL,GstVulkanHandlePool))
+#define GST_VULKAN_HANDLE_POOL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VULKAN_HANDLE_POOL,GstVulkanHandlePoolClass))
+#define GST_IS_VULKAN_HANDLE_POOL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VULKAN_HANDLE_POOL))
+#define GST_IS_VULKAN_HANDLE_POOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VULKAN_HANDLE_POOL))
+#define GST_VULKAN_HANDLE_POOL_GET_CLASS(o)    (G_TYPE_INSTANCE_GET_CLASS((o), GST_TYPE_VULKAN_HANDLE_POOL, GstVulkanHandlePoolClass))
+#define GST_VULKAN_HANDLE_POOL_CAST(o)         ((GstVulkanHandlePool *) o)
+
+struct _GstVulkanHandlePool
+{
+  GstObject                 parent;
+
+  GstVulkanDevice          *device;
+
+  /* <protected> */
+  GPtrArray                *outstanding;
+  GPtrArray                *available;
+
+  /* <private> */
+  gpointer                  _padding[GST_PADDING];
+};
+
+struct _GstVulkanHandlePoolClass
+{
+  GstObjectClass        parent;
+
+  gpointer              (*alloc)            (GstVulkanHandlePool * pool, GError ** error);
+  gpointer              (*acquire)          (GstVulkanHandlePool * pool, GError ** error);
+  void                  (*release)          (GstVulkanHandlePool * pool, gpointer handle);
+  void                  (*free)             (GstVulkanHandlePool * pool, gpointer handle);
+};
+
+GST_VULKAN_API
+gpointer        gst_vulkan_handle_pool_alloc        (GstVulkanHandlePool * pool, GError ** error);
+GST_VULKAN_API
+gpointer        gst_vulkan_handle_pool_acquire      (GstVulkanHandlePool * pool, GError ** error);
+GST_VULKAN_API
+void            gst_vulkan_handle_pool_release      (GstVulkanHandlePool * pool, gpointer handle);
+
+G_END_DECLS
+
+#endif /* _GST_VULKAN_HANDLE_H_ */
index 3000bb0..9219819 100644 (file)
@@ -1264,7 +1264,7 @@ reacquire:
     };
     /* *INDENT-ON* */
 
-    fence = gst_vulkan_fence_new (swapper->device, 0, error);
+    fence = gst_vulkan_device_create_fence (swapper->device, error);
     if (!fence)
       goto error;
 
@@ -1324,7 +1324,7 @@ reacquire:
     };
     /* *INDENT-ON* */
 
-    fence = gst_vulkan_fence_new (swapper->device, 0, error);
+    fence = gst_vulkan_device_create_fence (swapper->device, error);
     if (!fence)
       goto error;
 
index f911d16..abce93c 100644 (file)
@@ -28,6 +28,9 @@
 GST_DEBUG_CATEGORY (gst_debug_vulkan_trash);
 #define GST_CAT_DEFAULT gst_debug_vulkan_trash
 
+#define gst_vulkan_trash_release(c,t) \
+    gst_vulkan_handle_pool_release (GST_VULKAN_HANDLE_POOL_CAST (c), t);
+
 static void
 _init_debug (void)
 {
@@ -40,21 +43,68 @@ _init_debug (void)
   }
 }
 
+static gboolean
+gst_vulkan_trash_dispose (GstVulkanTrash * trash)
+{
+  GstVulkanTrashList *cache;
+
+  /* no pool, do free */
+  if ((cache = trash->cache) == NULL)
+    return TRUE;
+
+  /* keep the buffer alive */
+  gst_vulkan_trash_ref (trash);
+  /* return the buffer to the pool */
+  gst_vulkan_trash_release (cache, trash);
+
+  return FALSE;
+}
+
+static void
+gst_vulkan_trash_deinit (GstVulkanTrash * trash)
+{
+  if (trash->fence) {
+    g_warn_if_fail (gst_vulkan_fence_is_signaled (trash->fence));
+    gst_vulkan_fence_unref (trash->fence);
+    trash->fence = NULL;
+  }
+
+  trash->notify = NULL;
+  trash->user_data = NULL;
+}
+
 static void
 gst_vulkan_trash_free (GstMiniObject * object)
 {
   GstVulkanTrash *trash = (GstVulkanTrash *) object;
 
-  g_warn_if_fail (gst_vulkan_fence_is_signaled (trash->fence));
-
   GST_TRACE ("Freeing trash object %p with fence %" GST_PTR_FORMAT, trash,
       trash->fence);
 
-  gst_vulkan_fence_unref (trash->fence);
+  gst_vulkan_trash_deinit (trash);
 
   g_free (trash);
 }
 
+static void
+gst_vulkan_trash_init (GstVulkanTrash * trash, GstVulkanFence * fence,
+    GstVulkanTrashNotify notify, gpointer user_data)
+{
+  g_return_if_fail (fence != NULL);
+  g_return_if_fail (GST_IS_VULKAN_DEVICE (fence->device));
+  g_return_if_fail (notify != NULL);
+
+  gst_mini_object_init ((GstMiniObject *) trash, 0,
+      gst_vulkan_trash_get_type (), NULL,
+      (GstMiniObjectDisposeFunction) gst_vulkan_trash_dispose,
+      (GstMiniObjectFreeFunction) gst_vulkan_trash_free);
+  GST_TRACE ("Initializing trash object %p with fence %" GST_PTR_FORMAT
+      " on device %" GST_PTR_FORMAT, trash, fence, fence->device);
+  trash->fence = gst_vulkan_fence_ref (fence);
+  trash->notify = notify;
+  trash->user_data = user_data;
+}
+
 /**
  * gst_vulkan_trash_new:
  * @fence: a #GstVulkanFence
@@ -81,11 +131,7 @@ gst_vulkan_trash_new (GstVulkanFence * fence, GstVulkanTrashNotify notify,
   ret = g_new0 (GstVulkanTrash, 1);
   GST_TRACE ("Creating new trash object %p with fence %" GST_PTR_FORMAT
       " on device %" GST_PTR_FORMAT, ret, fence, fence->device);
-  gst_mini_object_init ((GstMiniObject *) ret, 0, gst_vulkan_trash_get_type (),
-      NULL, NULL, (GstMiniObjectFreeFunction) gst_vulkan_trash_free);
-  ret->fence = gst_vulkan_fence_ref (fence);
-  ret->notify = notify;
-  ret->user_data = user_data;
+  gst_vulkan_trash_init (ret, fence, notify, user_data);
 
   return ret;
 }
@@ -160,40 +206,21 @@ G_PASTE(gst_vulkan_trash_new_free_,type_name) (GstVulkanFence * fence, \
   return trash; \
 }
 
-static void
-_trash_object_unref (GstVulkanDevice * device, GstObject * object)
-{
-  gst_object_unref (object);
-}
-
-GstVulkanTrash *
-gst_vulkan_trash_new_object_unref (GstVulkanFence * fence, GstObject * object)
-{
-  GstVulkanTrash *trash;
-  g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
-  trash = gst_vulkan_trash_new (fence,
-      (GstVulkanTrashNotify) _trash_object_unref, object);
-  return trash;
-}
-
-static void
-_trash_mini_object_unref (GstVulkanDevice * device, GstMiniObject * object)
+void
+gst_vulkan_trash_object_unref (GstVulkanDevice * device, gpointer user_data)
 {
-  gst_mini_object_unref (object);
+  gst_object_unref ((GstObject *) user_data);
 }
 
-GstVulkanTrash *
-gst_vulkan_trash_new_mini_object_unref (GstVulkanFence * fence,
-    GstMiniObject * object)
+void
+gst_vulkan_trash_mini_object_unref (GstVulkanDevice * device,
+    gpointer user_data)
 {
-  GstVulkanTrash *trash;
-  g_return_val_if_fail (object != NULL, NULL);
-  trash = gst_vulkan_trash_new (fence,
-      (GstVulkanTrashNotify) _trash_mini_object_unref, object);
-  return trash;
+  gst_mini_object_unref ((GstMiniObject *) user_data);
 }
 
-G_DEFINE_TYPE (GstVulkanTrashList, gst_vulkan_trash_list, GST_TYPE_OBJECT);
+G_DEFINE_TYPE_WITH_CODE (GstVulkanTrashList, gst_vulkan_trash_list,
+    GST_TYPE_VULKAN_HANDLE_POOL, _init_debug ());
 
 void
 gst_vulkan_trash_list_gc (GstVulkanTrashList * trash_list)
@@ -229,9 +256,42 @@ gst_vulkan_trash_list_wait (GstVulkanTrashList * trash_list, guint64 timeout)
   return trash_class->wait_func (trash_list, timeout);
 }
 
+static gpointer
+gst_vulkan_trash_list_alloc_impl (GstVulkanHandlePool * pool, GError ** error)
+{
+  return g_new0 (GstVulkanTrash, 1);
+}
+
+static void
+gst_vulkan_trash_list_release_impl (GstVulkanHandlePool * pool, gpointer handle)
+{
+  GstVulkanTrash *trash = handle;
+
+  GST_TRACE_OBJECT (pool, "reset trash object %p", trash);
+
+  gst_vulkan_trash_deinit (trash);
+  gst_clear_object (&trash->cache);
+
+  GST_VULKAN_HANDLE_POOL_CLASS (gst_vulkan_trash_list_parent_class)->release
+      (pool, handle);
+}
+
+static void
+gst_vulkan_trash_list_free_impl (GstVulkanHandlePool * pool, gpointer handle)
+{
+  GstVulkanTrash *trash = handle;
+
+  gst_vulkan_trash_unref (trash);
+}
+
 static void
 gst_vulkan_trash_list_class_init (GstVulkanTrashListClass * klass)
 {
+  GstVulkanHandlePoolClass *pool_class = (GstVulkanHandlePoolClass *) klass;
+
+  pool_class->alloc = gst_vulkan_trash_list_alloc_impl;
+  pool_class->release = gst_vulkan_trash_list_release_impl;
+  pool_class->free = gst_vulkan_trash_list_free_impl;
 }
 
 static void
@@ -239,6 +299,27 @@ gst_vulkan_trash_list_init (GstVulkanTrashList * trash_list)
 {
 }
 
+GstVulkanTrash *
+gst_vulkan_trash_list_acquire (GstVulkanTrashList * trash_list,
+    GstVulkanFence * fence, GstVulkanTrashNotify notify, gpointer user_data)
+{
+  GstVulkanHandlePool *pool = GST_VULKAN_HANDLE_POOL (trash_list);
+  GstVulkanHandlePoolClass *pool_class;
+  GstVulkanTrash *trash;
+
+  g_return_val_if_fail (GST_IS_VULKAN_TRASH_LIST (trash_list), NULL);
+
+  pool_class = GST_VULKAN_HANDLE_POOL_GET_CLASS (trash_list);
+
+  trash = pool_class->acquire (pool, NULL);
+  gst_vulkan_trash_init (trash, fence, notify, user_data);
+  trash->cache = gst_object_ref (trash_list);
+
+  GST_TRACE_OBJECT (trash_list, "acquired trash object %p", trash);
+
+  return trash;
+}
+
 typedef struct _GstVulkanTrashFenceList GstVulkanTrashFenceList;
 
 struct _GstVulkanTrashFenceList
@@ -262,8 +343,8 @@ gst_vulkan_trash_fence_list_gc (GstVulkanTrashList * trash_list)
 
     if (gst_vulkan_fence_is_signaled (trash->fence)) {
       GList *next = g_list_next (l);
-      GST_TRACE ("fence %" GST_PTR_FORMAT " has been signalled, notifying",
-          trash->fence);
+      GST_TRACE_OBJECT (fence_list, "fence %" GST_PTR_FORMAT " has been "
+          "signalled, notifying", trash->fence);
       trash->notify (trash->fence->device, trash->user_data);
       gst_vulkan_trash_unref (trash);
       fence_list->list = g_list_delete_link (fence_list->list, l);
@@ -304,8 +385,8 @@ gst_vulkan_trash_fence_list_wait (GstVulkanTrashList * trash_list,
       g_assert (device == trash->fence->device);
     }
 
-    GST_TRACE ("Waiting on %d fences with timeout %" GST_TIME_FORMAT, n,
-        GST_TIME_ARGS (timeout));
+    GST_TRACE_OBJECT (trash_list, "Waiting on %d fences with timeout %"
+        GST_TIME_FORMAT, n, GST_TIME_ARGS (timeout));
     err = vkWaitForFences (device->device, n, fences, TRUE, timeout);
     g_free (fences);
 
index d009022..29e2b55 100644 (file)
@@ -31,10 +31,15 @@ struct _GstVulkanTrash
 {
   GstMiniObject         parent;
 
+  GstVulkanTrashList   *cache;
+
   GstVulkanFence       *fence;
 
   GstVulkanTrashNotify  notify;
   gpointer              user_data;
+
+  /* <private> */
+  gpointer              _padding[GST_PADDING];
 };
 
 #define GST_TYPE_VULKAN_TRASH gst_vulkan_trash_get_type()
@@ -79,18 +84,33 @@ GstVulkanTrash *    gst_vulkan_trash_new                            (GstVulkanFe
                                                                      GstVulkanTrashNotify notify,
                                                                      gpointer user_data);
 GST_VULKAN_API
-GstVulkanTrash *    gst_vulkan_trash_new_free_semaphore             (GstVulkanFence * fence,
-                                                                     VkSemaphore semaphore);
+void                gst_vulkan_trash_mini_object_unref              (GstVulkanDevice * device,
+                                                                     gpointer user_data);
 GST_VULKAN_API
-GstVulkanTrash *    gst_vulkan_trash_new_object_unref               (GstVulkanFence * fence,
-                                                                     GstObject * object);
+void                gst_vulkan_trash_object_unref                   (GstVulkanDevice * device,
+                                                                     gpointer user_data);
 GST_VULKAN_API
-GstVulkanTrash *    gst_vulkan_trash_new_mini_object_unref          (GstVulkanFence * fence,
-                                                                     GstMiniObject * object);
+GstVulkanTrash *    gst_vulkan_trash_new_free_semaphore             (GstVulkanFence * fence,
+                                                                     VkSemaphore semaphore);
+
+static inline GstVulkanTrash *
+gst_vulkan_trash_new_object_unref (GstVulkanFence * fence, GstObject * object)
+{
+  g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
+  return gst_vulkan_trash_new (fence,
+      (GstVulkanTrashNotify) gst_vulkan_trash_object_unref, (gpointer) object);
+}
+
+static inline GstVulkanTrash *
+gst_vulkan_trash_new_mini_object_unref (GstVulkanFence * fence, GstMiniObject * object)
+{
+  return gst_vulkan_trash_new (fence,
+      (GstVulkanTrashNotify) gst_vulkan_trash_mini_object_unref, (gpointer) object);
+}
 
-#define GST_TYPE_VULKAN_TRASH_LIST gst_vulkan_trash_list_get_type()
 GST_VULKAN_API
 GType gst_vulkan_trash_list_get_type (void);
+#define GST_TYPE_VULKAN_TRASH_LIST gst_vulkan_trash_list_get_type()
 #define GST_VULKAN_TRASH_LIST(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VULKAN_TRASH_LIST,GstVulkanTrashList))
 #define GST_VULKAN_TRASH_LIST_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VULKAN_TRASH_LIST,GstVulkanTrashListClass))
 #define GST_VULKAN_TRASH_LIST_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_VULKAN_TRASH_LIST,GstVulkanTrashListClass))
@@ -103,7 +123,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVulkanTrashList, gst_object_unref)
 
 struct _GstVulkanTrashList
 {
-  GstObject         parent;
+  GstVulkanHandlePool parent;
 };
 
 typedef void        (*GstVulkanTrashListGC)     (GstVulkanTrashList * trash_list);
@@ -112,7 +132,7 @@ typedef gboolean    (*GstVulkanTrashListWait)   (GstVulkanTrashList * trash_list
 
 struct _GstVulkanTrashListClass
 {
-  GstObjectClass            parent_class;
+  GstVulkanHandlePoolClass  parent_class;
 
   GstVulkanTrashListAdd     add_func;
   GstVulkanTrashListGC      gc_func;
@@ -129,6 +149,11 @@ gboolean            gst_vulkan_trash_list_wait                      (GstVulkanTr
 GST_VULKAN_API
 gboolean            gst_vulkan_trash_list_add                       (GstVulkanTrashList * trash_list,
                                                                      GstVulkanTrash * trash);
+GST_VULKAN_API
+GstVulkanTrash *    gst_vulkan_trash_list_acquire                   (GstVulkanTrashList * trash_list,
+                                                                     GstVulkanFence * fence,
+                                                                     GstVulkanTrashNotify notify,
+                                                                     gpointer user_data);
 
 GST_VULKAN_API
 G_DECLARE_FINAL_TYPE (GstVulkanTrashFenceList, gst_vulkan_trash_fence_list, GST, VULKAN_TRASH_FENCE_LIST, GstVulkanTrashList);
index 2878566..8b3268e 100644 (file)
@@ -18,6 +18,7 @@ vulkan_sources = [
   'gstvkfence.c',
   'gstvkformat.c',
   'gstvkhandle.c',
+  'gstvkhandlepool.c',
   'gstvkimagememory.c',
   'gstvkimagebufferpool.c',
   'gstvkimageview.c',
@@ -49,6 +50,7 @@ vulkan_headers = [
   'gstvkfence.h',
   'gstvkformat.h',
   'gstvkhandle.h',
+  'gstvkhandlepool.h',
   'gstvkimagememory.h',
   'gstvkimagebufferpool.h',
   'gstvkimageview.h',
index 0133793..bdf10f4 100644 (file)
@@ -50,6 +50,7 @@
 #include <gst/vulkan/gstvkdescriptorset.h>
 #include <gst/vulkan/gstvkdescriptorpool.h>
 #include <gst/vulkan/gstvkhandle.h>
+#include <gst/vulkan/gstvkhandlepool.h>
 #include <gst/vulkan/gstvktrash.h>
 #include <gst/vulkan/gstvkswapper.h>
 
index c542ccc..f489fc3 100644 (file)
@@ -69,6 +69,9 @@ typedef struct _GstVulkanWindowPrivate GstVulkanWindowPrivate;
 
 typedef struct _GstVulkanFence GstVulkanFence;
 
+typedef struct _GstVulkanFenceCache GstVulkanFenceCache;
+typedef struct _GstVulkanFenceCacheClass GstVulkanFenceCacheClass;
+
 typedef struct _GstVulkanMemory GstVulkanMemory;
 typedef struct _GstVulkanMemoryAllocator GstVulkanMemoryAllocator;
 typedef struct _GstVulkanMemoryAllocatorClass GstVulkanMemoryAllocatorClass;
@@ -83,6 +86,9 @@ typedef struct _GstVulkanBufferPoolPrivate GstVulkanBufferPoolPrivate;
 
 typedef struct _GstVulkanHandle GstVulkanHandle;
 
+typedef struct _GstVulkanHandlePool GstVulkanHandlePool;
+typedef struct _GstVulkanHandlePoolClass GstVulkanHandlePoolClass;
+
 typedef struct _GstVulkanImageMemory GstVulkanImageMemory;
 typedef struct _GstVulkanImageMemoryAllocator GstVulkanImageMemoryAllocator;
 typedef struct _GstVulkanImageMemoryAllocatorClass GstVulkanImageMemoryAllocatorClass;
index 6eabbf1..2432f87 100644 (file)
@@ -377,6 +377,7 @@ else
   message('Orc Compiler not found or disabled, will use backup C code')
   cdata.set('DISABLE_ORC', 1)
 endif
+cdata.set('GST_ENABLE_EXTRA_CHECKS', get_option('extra-checks'))
 
 gnustl_dep = declare_dependency()
 if host_system == 'android'
index b64c1ce..0bcb5c0 100644 (file)
@@ -181,6 +181,7 @@ option('glib-asserts', type : 'feature', value : 'enabled', yield : true,
        description: 'Enable GLib assertion (auto = enabled for development, disabled for stable releases)')
 option('glib-checks', type : 'feature', value : 'enabled', yield : true,
        description: 'Enable GLib checks such as API guards (auto = enabled for development, disabled for stable releases)')
+option('extra-checks', type : 'boolean', value : true, description : 'Enable extra runtime checks')
 
 # Common options
 option('package-name', type : 'string', yield : true,