We don't release GstD3D12Device intentionally, thus a GstD3D12FenceDataPool owned by a device will not be released but that's expected leak. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7243>
		
			
				
	
	
		
			294 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			294 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* GStreamer
 | |
|  * Copyright (C) 2023 Seungha Yang <seungha@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.
 | |
|  */
 | |
| 
 | |
| #ifdef HAVE_CONFIG_H
 | |
| #include "config.h"
 | |
| #endif
 | |
| 
 | |
| #include "gstd3d12fencedatapool.h"
 | |
| #include <gst/base/gstqueuearray.h>
 | |
| #include <mutex>
 | |
| #include <queue>
 | |
| 
 | |
| GST_DEBUG_CATEGORY_STATIC (gst_d3d12_fence_data_pool_debug);
 | |
| #define GST_CAT_DEFAULT gst_d3d12_fence_data_pool_debug
 | |
| 
 | |
| struct NotifyData
 | |
| {
 | |
|   gpointer user_data = nullptr;
 | |
|   GDestroyNotify notify = nullptr;
 | |
| };
 | |
| 
 | |
| static void
 | |
| notify_data_clear_func (NotifyData * data)
 | |
| {
 | |
|   if (data->notify)
 | |
|     data->notify (data->user_data);
 | |
| 
 | |
|   data->user_data = nullptr;
 | |
|   data->notify = nullptr;
 | |
| }
 | |
| 
 | |
| /* *INDENT-OFF* */
 | |
| struct _GstD3D12FenceData : public GstMiniObject
 | |
| {
 | |
|   _GstD3D12FenceData ()
 | |
|   {
 | |
|     queue = gst_vec_deque_new_for_struct (sizeof (NotifyData), 4);
 | |
|     gst_vec_deque_set_clear_func (queue,
 | |
|         (GDestroyNotify) notify_data_clear_func);
 | |
|   }
 | |
| 
 | |
|   ~_GstD3D12FenceData ()
 | |
|   {
 | |
|     gst_vec_deque_free (queue);
 | |
|   }
 | |
| 
 | |
|   GstD3D12FenceDataPool *pool = nullptr;
 | |
|   GstVecDeque *queue;
 | |
| };
 | |
| 
 | |
| GST_DEFINE_MINI_OBJECT_TYPE (GstD3D12FenceData, gst_d3d12_fence_data);
 | |
| 
 | |
| struct _GstD3D12FenceDataPoolPrivate
 | |
| {
 | |
|   ~_GstD3D12FenceDataPoolPrivate ()
 | |
|   {
 | |
|     while (!data_pool.empty ()) {
 | |
|       auto data = data_pool.front ();
 | |
|       data_pool.pop ();
 | |
|       gst_mini_object_unref (data);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   std::mutex lock;
 | |
|   std::queue<GstD3D12FenceData *>data_pool;
 | |
| };
 | |
| /* *INDENT-ON* */
 | |
| 
 | |
| static void gst_d3d12_fence_data_pool_finalize (GObject * object);
 | |
| 
 | |
| #define gst_d3d12_fence_data_pool_parent_class parent_class
 | |
| G_DEFINE_TYPE (GstD3D12FenceDataPool,
 | |
|     gst_d3d12_fence_data_pool, GST_TYPE_OBJECT);
 | |
| 
 | |
| static void
 | |
| gst_d3d12_fence_data_pool_class_init (GstD3D12FenceDataPoolClass * klass)
 | |
| {
 | |
|   auto object_class = G_OBJECT_CLASS (klass);
 | |
| 
 | |
|   object_class->finalize = gst_d3d12_fence_data_pool_finalize;
 | |
| 
 | |
|   GST_DEBUG_CATEGORY_INIT (gst_d3d12_fence_data_pool_debug,
 | |
|       "d3d12fencedatapool", 0, "d3d12fencedatapool");
 | |
| }
 | |
| 
 | |
| static void
 | |
| gst_d3d12_fence_data_pool_init (GstD3D12FenceDataPool * self)
 | |
| {
 | |
|   self->priv = new GstD3D12FenceDataPoolPrivate ();
 | |
| }
 | |
| 
 | |
| static void
 | |
| gst_d3d12_fence_data_pool_finalize (GObject * object)
 | |
| {
 | |
|   auto self = GST_D3D12_FENCE_DATA_POOL (object);
 | |
| 
 | |
|   delete self->priv;
 | |
| 
 | |
|   G_OBJECT_CLASS (parent_class)->finalize (object);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * gst_d3d12_fence_data_pool_new:
 | |
|  *
 | |
|  * Creates #GstD3D12FenceDataPool instance
 | |
|  *
 | |
|  * Returns: (transfer full): a #GstD3D12FenceDataPool instance
 | |
|  *
 | |
|  * Since: 1.26
 | |
|  */
 | |
| GstD3D12FenceDataPool *
 | |
| gst_d3d12_fence_data_pool_new (void)
 | |
| {
 | |
|   auto self = (GstD3D12FenceDataPool *)
 | |
|       g_object_new (GST_TYPE_D3D12_FENCE_DATA_POOL, nullptr);
 | |
|   gst_object_ref_sink (self);
 | |
| 
 | |
|   return self;
 | |
| }
 | |
| 
 | |
| static void
 | |
| gst_d3d12_fence_data_pool_release (GstD3D12FenceDataPool * pool,
 | |
|     GstD3D12FenceData * data)
 | |
| {
 | |
|   auto priv = pool->priv;
 | |
|   gst_vec_deque_clear (data->queue);
 | |
| 
 | |
|   {
 | |
|     std::lock_guard < std::mutex > lk (priv->lock);
 | |
|     data->dispose = nullptr;
 | |
|     data->pool = nullptr;
 | |
|     priv->data_pool.push (data);
 | |
|   }
 | |
| 
 | |
|   gst_object_unref (pool);
 | |
| }
 | |
| 
 | |
| static void
 | |
| gst_d3d12_fence_data_free (GstD3D12FenceData * data)
 | |
| {
 | |
|   delete data;
 | |
| }
 | |
| 
 | |
| static gboolean
 | |
| gst_d3d12_fence_data_dispose (GstD3D12FenceData * data)
 | |
| {
 | |
|   if (!data->pool)
 | |
|     return TRUE;
 | |
| 
 | |
|   gst_mini_object_ref (data);
 | |
|   gst_d3d12_fence_data_pool_release (data->pool, data);
 | |
|   return FALSE;
 | |
| }
 | |
| 
 | |
| static GstD3D12FenceData *
 | |
| gst_d3d12_fence_data_new (void)
 | |
| {
 | |
|   auto data = new GstD3D12FenceData ();
 | |
| 
 | |
|   gst_mini_object_init (data, 0, gst_d3d12_fence_data_get_type (),
 | |
|       nullptr, nullptr, (GstMiniObjectFreeFunction) gst_d3d12_fence_data_free);
 | |
| 
 | |
|   return data;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * gst_d3d12_fence_data_pool_acquire:
 | |
|  * @pool: a #GstD3D12FenceDataPool
 | |
|  * @data: (out) (transfer full): a pointer to #GstD3D12FenceData
 | |
|  *
 | |
|  * Acquire #GstD3D12CommandAllocator object
 | |
|  *
 | |
|  * Returns: %TRUE if successful
 | |
|  *
 | |
|  * Since: 1.26
 | |
|  */
 | |
| gboolean
 | |
| gst_d3d12_fence_data_pool_acquire (GstD3D12FenceDataPool * pool,
 | |
|     GstD3D12FenceData ** data)
 | |
| {
 | |
|   g_return_val_if_fail (GST_IS_D3D12_FENCE_DATA_POOL (pool), FALSE);
 | |
|   g_return_val_if_fail (data, FALSE);
 | |
| 
 | |
|   auto priv = pool->priv;
 | |
|   GstD3D12FenceData *new_data = nullptr;
 | |
| 
 | |
|   {
 | |
|     std::lock_guard < std::mutex > lk (priv->lock);
 | |
|     if (!priv->data_pool.empty ()) {
 | |
|       new_data = priv->data_pool.front ();
 | |
|       priv->data_pool.pop ();
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (!new_data) {
 | |
|     new_data = gst_d3d12_fence_data_new ();
 | |
| 
 | |
|     if (GST_OBJECT_FLAG_IS_SET (pool, GST_OBJECT_FLAG_MAY_BE_LEAKED))
 | |
|       GST_MINI_OBJECT_FLAG_SET (new_data, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
 | |
|   }
 | |
| 
 | |
|   new_data->pool = (GstD3D12FenceDataPool *) gst_object_ref (pool);
 | |
|   new_data->dispose =
 | |
|       (GstMiniObjectDisposeFunction) gst_d3d12_fence_data_dispose;
 | |
| 
 | |
|   *data = new_data;
 | |
| 
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * gst_d3d12_fence_data_push:
 | |
|  * @data: a #GstD3D12FenceData
 | |
|  * @user_data: private data
 | |
|  * @notify: a #GDestroyNotify
 | |
|  *
 | |
|  * Sets notify callback
 | |
|  *
 | |
|  * Since: 1.26
 | |
|  */
 | |
| void
 | |
| gst_d3d12_fence_data_push (GstD3D12FenceData * data, gpointer user_data,
 | |
|     GDestroyNotify notify)
 | |
| {
 | |
|   g_return_if_fail (data);
 | |
| 
 | |
|   NotifyData notify_data;
 | |
| 
 | |
|   notify_data.user_data = user_data;
 | |
|   notify_data.notify = notify;
 | |
| 
 | |
|   gst_vec_deque_push_tail_struct (data->queue, ¬ify_data);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * gst_d3d12_fence_data_ref:
 | |
|  * @data: a #GstD3D12FenceData
 | |
|  *
 | |
|  * Increments the refcount of @data
 | |
|  *
 | |
|  * Returns: (transfer full): a #GstD3D12FenceData
 | |
|  *
 | |
|  * Since: 1.26
 | |
|  */
 | |
| GstD3D12FenceData *
 | |
| gst_d3d12_fence_data_ref (GstD3D12FenceData * data)
 | |
| {
 | |
|   return (GstD3D12FenceData *) gst_mini_object_ref (data);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * gst_d3d12_fence_data_unref:
 | |
|  * @cmd: a #GstD3D12FenceData
 | |
|  *
 | |
|  * Decrements the refcount of @data
 | |
|  *
 | |
|  * Since: 1.26
 | |
|  */
 | |
| void
 | |
| gst_d3d12_fence_data_unref (GstD3D12FenceData * data)
 | |
| {
 | |
|   gst_mini_object_unref (data);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * gst_clear_d3d12_fence_data:
 | |
|  * @data: a pointer to #GstD3D12FenceData
 | |
|  *
 | |
|  * Clears a reference to a #GstD3D12FenceData
 | |
|  *
 | |
|  * Since: 1.26
 | |
|  */
 | |
| void
 | |
| gst_clear_d3d12_fence_data (GstD3D12FenceData ** data)
 | |
| {
 | |
|   gst_clear_mini_object (data);
 | |
| }
 |