mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 14:56:36 +00:00
vulkan/window/ios: fix race on window startup
1. The iOS create_surface implementation needs to call out to the main thread to create the window (UIKit requirement) 2. get_surface() can be called and will attempt to create the VkSurface from an invalid view/layer. Also pass the layer for MoltenVK so we don't get pesky 'UIView function not called on main thread' warnings.
This commit is contained in:
parent
656a0cde84
commit
cd28c77413
1 changed files with 38 additions and 3 deletions
|
@ -59,10 +59,14 @@ enum
|
|||
struct _GstVulkanWindowIosPrivate
|
||||
{
|
||||
gpointer internal_view;
|
||||
gpointer internal_layer;
|
||||
gpointer external_view;
|
||||
|
||||
gint preferred_width;
|
||||
gint preferred_height;
|
||||
|
||||
GMutex lock;
|
||||
GCond cond;
|
||||
};
|
||||
|
||||
#define gst_vulkan_window_ios_parent_class parent_class
|
||||
|
@ -82,6 +86,11 @@ static void gst_vulkan_window_ios_set_window_handle (GstVulkanWindow * window,
|
|||
static void
|
||||
gst_vulkan_window_ios_finalize (GObject * object)
|
||||
{
|
||||
GstVulkanWindowIos *window_ios = GST_VULKAN_WINDOW_IOS (object);
|
||||
|
||||
g_mutex_clear (&window_ios->priv->lock);
|
||||
g_cond_clear (&window_ios->priv->cond);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
@ -109,6 +118,9 @@ gst_vulkan_window_ios_init (GstVulkanWindowIos * window)
|
|||
|
||||
window->priv->preferred_width = 320;
|
||||
window->priv->preferred_height = 240;
|
||||
|
||||
g_mutex_init (&window->priv->lock);
|
||||
g_cond_init (&window->priv->cond);
|
||||
}
|
||||
|
||||
/* Must be called in the gl thread */
|
||||
|
@ -146,14 +158,22 @@ _create_window (GstVulkanWindowIos * window_ios)
|
|||
view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
view.contentMode = UIViewContentModeRedraw;
|
||||
|
||||
priv->internal_view = (__bridge_retained gpointer)view;
|
||||
g_mutex_lock (&priv->lock);
|
||||
|
||||
priv->internal_view = (__bridge_retained gpointer) view;
|
||||
[external_view addSubview:view];
|
||||
priv->internal_layer = (__bridge_retained gpointer) [view layer];
|
||||
|
||||
g_cond_broadcast (&priv->cond);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vulkan_window_ios_create_window (GstVulkanWindowIos * window_ios)
|
||||
{
|
||||
if (!window_ios->priv->external_view) {
|
||||
GstVulkanWindowIosPrivate *priv = window_ios->priv;
|
||||
|
||||
if (!priv->external_view) {
|
||||
GST_WARNING_OBJECT(window_ios, "No external UIView provided");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -161,6 +181,12 @@ gst_vulkan_window_ios_create_window (GstVulkanWindowIos * window_ios)
|
|||
_invoke_on_main ((GstVulkanWindowFunc) _create_window,
|
||||
gst_object_ref (window_ios), gst_object_unref);
|
||||
|
||||
/* XXX: Maybe we need an async create_window/get_surface()? */
|
||||
g_mutex_lock (&priv->lock);
|
||||
while (!priv->internal_view)
|
||||
g_cond_wait (&priv->cond, &priv->lock);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -172,10 +198,17 @@ gst_vulkan_window_ios_get_surface (GstVulkanWindow * window, GError ** error)
|
|||
VkSurfaceKHR ret;
|
||||
VkResult err;
|
||||
|
||||
if (!window_ios->priv->internal_layer) {
|
||||
g_set_error_literal (error, GST_VULKAN_ERROR,
|
||||
VK_ERROR_INITIALIZATION_FAILED,
|
||||
"No layer to retrieve surface for. Has create_window() been called?");
|
||||
return 0;
|
||||
}
|
||||
|
||||
info.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK;
|
||||
info.pNext = NULL;
|
||||
info.flags = 0;
|
||||
info.pView = window_ios->priv->internal_view;
|
||||
info.pView = window_ios->priv->internal_layer;
|
||||
|
||||
if (!window_ios->CreateIOSSurface)
|
||||
window_ios->CreateIOSSurface =
|
||||
|
@ -223,6 +256,8 @@ gst_vulkan_window_ios_close (GstVulkanWindow * window)
|
|||
[view setGstWindow:NULL];
|
||||
CFBridgingRelease (window_ios->priv->internal_view);
|
||||
window_ios->priv->internal_view = NULL;
|
||||
CFBridgingRelease (window_ios->priv->internal_layer);
|
||||
window_ios->priv->internal_layer = NULL;
|
||||
|
||||
GST_VULKAN_WINDOW_CLASS (parent_class)->close (window);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue