mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +00:00
vulkan: implement quitting and resizing the window
As before, only xcb has been implemented.
This commit is contained in:
parent
5de6dd9f40
commit
216a321319
10 changed files with 240 additions and 59 deletions
|
@ -74,9 +74,39 @@ static GstVulkanWindow
|
||||||
|
|
||||||
struct _GstVulkanDisplayPrivate
|
struct _GstVulkanDisplayPrivate
|
||||||
{
|
{
|
||||||
gint dummy;
|
GThread *event_thread;
|
||||||
|
|
||||||
|
GMutex thread_lock;
|
||||||
|
GCond thread_cond;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static gpointer
|
||||||
|
_event_thread_main (GstVulkanDisplay * display)
|
||||||
|
{
|
||||||
|
g_mutex_lock (&display->priv->thread_lock);
|
||||||
|
|
||||||
|
display->main_context = g_main_context_new ();
|
||||||
|
display->main_loop = g_main_loop_new (display->main_context, FALSE);
|
||||||
|
|
||||||
|
g_cond_broadcast (&display->priv->thread_cond);
|
||||||
|
g_mutex_unlock (&display->priv->thread_lock);
|
||||||
|
|
||||||
|
g_main_loop_run (display->main_loop);
|
||||||
|
|
||||||
|
g_mutex_lock (&display->priv->thread_lock);
|
||||||
|
|
||||||
|
g_main_loop_unref (display->main_loop);
|
||||||
|
g_main_context_unref (display->main_context);
|
||||||
|
|
||||||
|
display->main_loop = NULL;
|
||||||
|
display->main_context = NULL;
|
||||||
|
|
||||||
|
g_cond_broadcast (&display->priv->thread_cond);
|
||||||
|
g_mutex_unlock (&display->priv->thread_lock);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_vulkan_display_class_init (GstVulkanDisplayClass * klass)
|
gst_vulkan_display_class_init (GstVulkanDisplayClass * klass)
|
||||||
{
|
{
|
||||||
|
@ -94,11 +124,42 @@ gst_vulkan_display_init (GstVulkanDisplay * display)
|
||||||
{
|
{
|
||||||
display->priv = GST_VULKAN_DISPLAY_GET_PRIVATE (display);
|
display->priv = GST_VULKAN_DISPLAY_GET_PRIVATE (display);
|
||||||
display->type = GST_VULKAN_DISPLAY_TYPE_ANY;
|
display->type = GST_VULKAN_DISPLAY_TYPE_ANY;
|
||||||
|
|
||||||
|
g_mutex_init (&display->priv->thread_lock);
|
||||||
|
g_cond_init (&display->priv->thread_cond);
|
||||||
|
|
||||||
|
display->priv->event_thread = g_thread_new ("vkdisplay-event",
|
||||||
|
(GThreadFunc) _event_thread_main, display);
|
||||||
|
|
||||||
|
g_mutex_lock (&display->priv->thread_lock);
|
||||||
|
while (!display->main_loop)
|
||||||
|
g_cond_wait (&display->priv->thread_cond, &display->priv->thread_lock);
|
||||||
|
g_mutex_unlock (&display->priv->thread_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_vulkan_display_finalize (GObject * object)
|
gst_vulkan_display_finalize (GObject * object)
|
||||||
{
|
{
|
||||||
|
GstVulkanDisplay *display = GST_VULKAN_DISPLAY (object);
|
||||||
|
|
||||||
|
g_mutex_lock (&display->priv->thread_lock);
|
||||||
|
if (display->main_context && display->event_source) {
|
||||||
|
g_source_destroy (display->event_source);
|
||||||
|
g_source_unref (display->event_source);
|
||||||
|
}
|
||||||
|
display->event_source = NULL;
|
||||||
|
|
||||||
|
if (display->main_loop)
|
||||||
|
g_main_loop_quit (display->main_loop);
|
||||||
|
|
||||||
|
while (display->main_loop)
|
||||||
|
g_cond_wait (&display->priv->thread_cond, &display->priv->thread_lock);
|
||||||
|
|
||||||
|
if (display->priv->event_thread)
|
||||||
|
g_thread_unref (display->priv->event_thread);
|
||||||
|
display->priv->event_thread = NULL;
|
||||||
|
g_mutex_unlock (&display->priv->thread_lock);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gst_vulkan_display_parent_class)->finalize (object);
|
G_OBJECT_CLASS (gst_vulkan_display_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +197,7 @@ gst_vulkan_display_new (void)
|
||||||
"(platform: %s), creating dummy",
|
"(platform: %s), creating dummy",
|
||||||
GST_STR_NULL (user_choice), GST_STR_NULL (platform_choice));
|
GST_STR_NULL (user_choice), GST_STR_NULL (platform_choice));
|
||||||
|
|
||||||
return g_object_new (GST_TYPE_VULKAN_DISPLAY, NULL);
|
display = g_object_new (GST_TYPE_VULKAN_DISPLAY, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return display;
|
return display;
|
||||||
|
@ -244,3 +305,21 @@ gst_vulkan_display_default_create_window (GstVulkanDisplay * display)
|
||||||
{
|
{
|
||||||
return gst_vulkan_window_new (display);
|
return gst_vulkan_window_new (display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_vulkan_display_remove_window (GstVulkanDisplay * display,
|
||||||
|
GstVulkanWindow * window)
|
||||||
|
{
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (display);
|
||||||
|
l = g_list_find (display->windows, window);
|
||||||
|
if (l) {
|
||||||
|
display->windows = g_list_delete_link (display->windows, l);
|
||||||
|
ret = TRUE;
|
||||||
|
}
|
||||||
|
GST_OBJECT_UNLOCK (display);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -66,7 +66,11 @@ struct _GstVulkanDisplay
|
||||||
|
|
||||||
/* <protected> */
|
/* <protected> */
|
||||||
GList *windows; /* OBJECT lock */
|
GList *windows; /* OBJECT lock */
|
||||||
|
GMainContext *main_context;
|
||||||
|
GMainLoop *main_loop;
|
||||||
|
GSource *event_source;
|
||||||
|
|
||||||
|
/* <private> */
|
||||||
GstVulkanDisplayPrivate *priv;
|
GstVulkanDisplayPrivate *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -86,6 +90,9 @@ GstVulkanDisplayType gst_vulkan_display_get_handle_type (GstVulkanDisplay
|
||||||
gpointer gst_vulkan_display_get_platform_handle (GstVulkanDisplay * display);
|
gpointer gst_vulkan_display_get_platform_handle (GstVulkanDisplay * display);
|
||||||
GstVulkanWindow * gst_vulkan_display_create_window (GstVulkanDisplay * display);
|
GstVulkanWindow * gst_vulkan_display_create_window (GstVulkanDisplay * display);
|
||||||
|
|
||||||
|
/* GstVulkanWindow usage only */
|
||||||
|
gboolean gst_vulkan_display_remove_window (GstVulkanDisplay * display, GstVulkanWindow * window);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GST_VULKAN_DISPLAY_H__ */
|
#endif /* __GST_VULKAN_DISPLAY_H__ */
|
||||||
|
|
|
@ -56,9 +56,6 @@ struct _GstVulkanSink
|
||||||
|
|
||||||
/* stream configuration */
|
/* stream configuration */
|
||||||
GstVideoInfo v_info;
|
GstVideoInfo v_info;
|
||||||
|
|
||||||
/* runtime variables */
|
|
||||||
gint to_quit;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstVulkanSinkClass
|
struct _GstVulkanSinkClass
|
||||||
|
|
|
@ -40,11 +40,16 @@ _get_function_table (GstVulkanSwapper * swapper)
|
||||||
GstVulkanDevice *device = swapper->device;
|
GstVulkanDevice *device = swapper->device;
|
||||||
GstVulkanInstance *instance = gst_vulkan_device_get_instance (device);
|
GstVulkanInstance *instance = gst_vulkan_device_get_instance (device);
|
||||||
|
|
||||||
|
if (!instance) {
|
||||||
|
GST_ERROR_OBJECT (swapper, "Failed to get instance from the device");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
#define GET_PROC_ADDRESS_REQUIRED(obj, type, name) \
|
#define GET_PROC_ADDRESS_REQUIRED(obj, type, name) \
|
||||||
G_STMT_START { \
|
G_STMT_START { \
|
||||||
obj->G_PASTE (, name) = G_PASTE(G_PASTE(gst_vulkan_, type), _get_proc_address) (type, "vk" G_STRINGIFY(name)); \
|
obj->G_PASTE (, name) = G_PASTE(G_PASTE(gst_vulkan_, type), _get_proc_address) (type, "vk" G_STRINGIFY(name)); \
|
||||||
if (!obj->G_PASTE(, name)) { \
|
if (!obj->G_PASTE(, name)) { \
|
||||||
GST_ERROR_OBJECT (obj, "Failed to find required function vk" G_STRINGIFY(name)); \
|
GST_ERROR_OBJECT (obj, "Failed to find required function vk" G_STRINGIFY(name)); \
|
||||||
|
gst_object_unref (instance); \
|
||||||
return FALSE; \
|
return FALSE; \
|
||||||
} \
|
} \
|
||||||
} G_STMT_END
|
} G_STMT_END
|
||||||
|
@ -60,6 +65,8 @@ _get_function_table (GstVulkanSwapper * swapper)
|
||||||
GET_PROC_ADDRESS_REQUIRED (swapper, device, AcquireNextImageKHR);
|
GET_PROC_ADDRESS_REQUIRED (swapper, device, AcquireNextImageKHR);
|
||||||
GET_PROC_ADDRESS_REQUIRED (swapper, device, QueuePresentKHR);
|
GET_PROC_ADDRESS_REQUIRED (swapper, device, QueuePresentKHR);
|
||||||
|
|
||||||
|
gst_object_unref (instance);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
#undef GET_PROC_ADDRESS_REQUIRED
|
#undef GET_PROC_ADDRESS_REQUIRED
|
||||||
|
@ -102,6 +109,7 @@ _get_window_surface_description (GstVulkanSwapper * swapper,
|
||||||
desc->platform = _gst_display_type_to_vk_platform (dtype);
|
desc->platform = _gst_display_type_to_vk_platform (dtype);
|
||||||
if (desc->platform == -1) {
|
if (desc->platform == -1) {
|
||||||
GST_ERROR_OBJECT (swapper, "Failed to retrieve platform from display");
|
GST_ERROR_OBJECT (swapper, "Failed to retrieve platform from display");
|
||||||
|
gst_object_unref (display);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,8 +210,8 @@ _vulkan_swapper_retrieve_surface_properties (GstVulkanSwapper * swapper,
|
||||||
|
|
||||||
swapper->GetPhysicalDeviceSurfaceSupportKHR (gpu, i,
|
swapper->GetPhysicalDeviceSurfaceSupportKHR (gpu, i,
|
||||||
(VkSurfaceDescriptionKHR *) & surface_desc, &supports_present);
|
(VkSurfaceDescriptionKHR *) & surface_desc, &supports_present);
|
||||||
if ((swapper->device->
|
if ((swapper->device->queue_family_props[i].
|
||||||
queue_family_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0) {
|
queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0) {
|
||||||
if (supports_present) {
|
if (supports_present) {
|
||||||
/* found one that supports both */
|
/* found one that supports both */
|
||||||
graphics_queue = present_queue = i;
|
graphics_queue = present_queue = i;
|
||||||
|
@ -270,6 +278,14 @@ _vulkan_swapper_retrieve_surface_properties (GstVulkanSwapper * swapper,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_on_window_close (GstVulkanWindow * window, GstVulkanSwapper * swapper)
|
||||||
|
{
|
||||||
|
g_atomic_int_set (&swapper->to_quit, 1);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_vulkan_swapper_finalize (GObject * object)
|
gst_vulkan_swapper_finalize (GObject * object)
|
||||||
{
|
{
|
||||||
|
@ -297,6 +313,9 @@ gst_vulkan_swapper_finalize (GObject * object)
|
||||||
gst_object_unref (swapper->device);
|
gst_object_unref (swapper->device);
|
||||||
swapper->device = NULL;
|
swapper->device = NULL;
|
||||||
|
|
||||||
|
g_signal_handler_disconnect (swapper->window, swapper->close_id);
|
||||||
|
swapper->close_id = 0;
|
||||||
|
|
||||||
if (swapper->window)
|
if (swapper->window)
|
||||||
gst_object_unref (swapper->window);
|
gst_object_unref (swapper->window);
|
||||||
swapper->window = NULL;
|
swapper->window = NULL;
|
||||||
|
@ -335,6 +354,9 @@ gst_vulkan_swapper_new (GstVulkanDevice * device, GstVulkanWindow * window)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
swapper->close_id = g_signal_connect (swapper->window, "close",
|
||||||
|
(GCallback) _on_window_close, swapper);
|
||||||
|
|
||||||
return swapper;
|
return swapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,6 +513,19 @@ _allocate_swapchain (GstVulkanSwapper * swapper, GstCaps * caps,
|
||||||
VkResult err;
|
VkResult err;
|
||||||
guint32 i;
|
guint32 i;
|
||||||
|
|
||||||
|
if (!_get_window_surface_description (swapper, &surface_desc)) {
|
||||||
|
g_set_error (error, GST_VULKAN_ERROR,
|
||||||
|
GST_VULKAN_ERROR_INITIALIZATION_FAILED,
|
||||||
|
"Failed to retrieve platform description");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
err =
|
||||||
|
swapper->GetSurfacePropertiesKHR (swapper->device->device,
|
||||||
|
(VkSurfaceDescriptionKHR *) & surface_desc, &swapper->surf_props);
|
||||||
|
if (gst_vulkan_error_to_g_error (err, error, "vkGetSurfacePropertiesKHR") < 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
/* width and height are either both -1, or both not -1. */
|
/* width and height are either both -1, or both not -1. */
|
||||||
if (swapper->surf_props.currentExtent.width == -1) {
|
if (swapper->surf_props.currentExtent.width == -1) {
|
||||||
/* If the surface size is undefined, the size is set to
|
/* If the surface size is undefined, the size is set to
|
||||||
|
@ -528,20 +563,13 @@ _allocate_swapchain (GstVulkanSwapper * swapper, GstCaps * caps,
|
||||||
n_images_wanted = swapper->surf_props.maxImageCount;
|
n_images_wanted = swapper->surf_props.maxImageCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (swapper->surf_props.
|
if (swapper->
|
||||||
supportedTransforms & VK_SURFACE_TRANSFORM_NONE_BIT_KHR) {
|
surf_props.supportedTransforms & VK_SURFACE_TRANSFORM_NONE_BIT_KHR) {
|
||||||
preTransform = VK_SURFACE_TRANSFORM_NONE_KHR;
|
preTransform = VK_SURFACE_TRANSFORM_NONE_KHR;
|
||||||
} else {
|
} else {
|
||||||
preTransform = swapper->surf_props.currentTransform;
|
preTransform = swapper->surf_props.currentTransform;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_get_window_surface_description (swapper, &surface_desc)) {
|
|
||||||
g_set_error (error, GST_VULKAN_ERROR,
|
|
||||||
GST_VULKAN_ERROR_INITIALIZATION_FAILED,
|
|
||||||
"Failed to retrieve platform description");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
format =
|
format =
|
||||||
_vk_format_from_video_format (GST_VIDEO_INFO_FORMAT (&swapper->v_info));
|
_vk_format_from_video_format (GST_VIDEO_INFO_FORMAT (&swapper->v_info));
|
||||||
color_space = _vk_color_space_from_video_info (&swapper->v_info);
|
color_space = _vk_color_space_from_video_info (&swapper->v_info);
|
||||||
|
@ -555,8 +583,8 @@ _allocate_swapchain (GstVulkanSwapper * swapper, GstCaps * caps,
|
||||||
"Incorrect usage flags available for the swap images");
|
"Incorrect usage flags available for the swap images");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if ((swapper->
|
if ((swapper->surf_props.
|
||||||
surf_props.supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
|
supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
|
||||||
!= 0) {
|
!= 0) {
|
||||||
usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||||
} else {
|
} else {
|
||||||
|
@ -887,6 +915,12 @@ gst_vulkan_swapper_render_buffer (GstVulkanSwapper * swapper,
|
||||||
guint32 swap_idx;
|
guint32 swap_idx;
|
||||||
VkResult err;
|
VkResult err;
|
||||||
|
|
||||||
|
if (g_atomic_int_get (&swapper->to_quit)) {
|
||||||
|
g_set_error (error, GST_VULKAN_ERROR, GST_VULKAN_ERROR_DEVICE_LOST,
|
||||||
|
"Output window was closed");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
reacquire:
|
reacquire:
|
||||||
err = vkCreateSemaphore (swapper->device->device, &semaphore_info,
|
err = vkCreateSemaphore (swapper->device->device, &semaphore_info,
|
||||||
&semaphore);
|
&semaphore);
|
||||||
|
@ -898,6 +932,8 @@ reacquire:
|
||||||
swapper->swap_chain, -1, semaphore, &swap_idx);
|
swapper->swap_chain, -1, semaphore, &swap_idx);
|
||||||
/* TODO: Deal with the VK_SUBOPTIMAL_KHR and VK_ERROR_OUT_OF_DATE_KHR */
|
/* TODO: Deal with the VK_SUBOPTIMAL_KHR and VK_ERROR_OUT_OF_DATE_KHR */
|
||||||
if (err == VK_ERROR_OUT_OF_DATE_KHR) {
|
if (err == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||||
|
GST_DEBUG_OBJECT (swapper, "out of date frame acquired");
|
||||||
|
|
||||||
vkDestroySemaphore (swapper->device->device, semaphore);
|
vkDestroySemaphore (swapper->device->device, semaphore);
|
||||||
if (!_swapchain_resize (swapper, error))
|
if (!_swapchain_resize (swapper, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -920,11 +956,24 @@ reacquire:
|
||||||
|
|
||||||
err = swapper->QueuePresentKHR (swapper->queue->queue, &present);
|
err = swapper->QueuePresentKHR (swapper->queue->queue, &present);
|
||||||
if (err == VK_ERROR_OUT_OF_DATE_KHR) {
|
if (err == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||||
|
GST_DEBUG_OBJECT (swapper, "out of date frame submitted");
|
||||||
|
|
||||||
vkDestroySemaphore (swapper->device->device, semaphore);
|
vkDestroySemaphore (swapper->device->device, semaphore);
|
||||||
|
|
||||||
if (!_swapchain_resize (swapper, error))
|
if (!_swapchain_resize (swapper, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
/* FIXME: correct? */
|
|
||||||
return TRUE;
|
if (cmd_data.cmd)
|
||||||
|
vkDestroyCommandBuffer (swapper->device->device, cmd_data.cmd);
|
||||||
|
cmd_data.cmd = NULL;
|
||||||
|
if (cmd_data.fence.handle)
|
||||||
|
vkDestroyFence (swapper->device->device, cmd_data.fence);
|
||||||
|
cmd_data.fence.handle = 0;
|
||||||
|
if (cmd_data.notify)
|
||||||
|
cmd_data.notify (cmd_data.data);
|
||||||
|
cmd_data.notify = NULL;
|
||||||
|
|
||||||
|
goto reacquire;
|
||||||
} else if (gst_vulkan_error_to_g_error (err, error, "vkQueuePresentKHR") < 0)
|
} else if (gst_vulkan_error_to_g_error (err, error, "vkQueuePresentKHR") < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,13 @@ struct _GstVulkanSwapper
|
||||||
PFN_vkGetSwapchainImagesKHR GetSwapchainImagesKHR;
|
PFN_vkGetSwapchainImagesKHR GetSwapchainImagesKHR;
|
||||||
PFN_vkAcquireNextImageKHR AcquireNextImageKHR;
|
PFN_vkAcquireNextImageKHR AcquireNextImageKHR;
|
||||||
PFN_vkQueuePresentKHR QueuePresentKHR;
|
PFN_vkQueuePresentKHR QueuePresentKHR;
|
||||||
|
|
||||||
|
/* <private> */
|
||||||
|
/* runtime variables */
|
||||||
|
gint to_quit;
|
||||||
|
|
||||||
|
/* signal handlers */
|
||||||
|
gulong close_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstVulkanSwapperClass
|
struct _GstVulkanSwapperClass
|
||||||
|
|
|
@ -78,10 +78,23 @@ GstVulkanDummyWindow *gst_vulkan_dummy_window_new (void);
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
SIGNAL_0,
|
SIGNAL_0,
|
||||||
|
SIGNAL_CLOSE,
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
/* static guint gst_vulkan_window_signals[LAST_SIGNAL] = { 0 }; */
|
static guint gst_vulkan_window_signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_accum_logical_and (GSignalInvocationHint * ihint, GValue * return_accu,
|
||||||
|
const GValue * handler_return, gpointer data)
|
||||||
|
{
|
||||||
|
gboolean val = g_value_get_boolean (handler_return);
|
||||||
|
gboolean val2 = g_value_get_boolean (return_accu);
|
||||||
|
|
||||||
|
g_value_set_boolean (return_accu, val && val2);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
GQuark
|
GQuark
|
||||||
gst_vulkan_window_error_quark (void)
|
gst_vulkan_window_error_quark (void)
|
||||||
|
@ -115,6 +128,9 @@ _init_debug (void)
|
||||||
static void
|
static void
|
||||||
gst_vulkan_window_init (GstVulkanWindow * window)
|
gst_vulkan_window_init (GstVulkanWindow * window)
|
||||||
{
|
{
|
||||||
|
window->priv =
|
||||||
|
G_TYPE_INSTANCE_GET_PRIVATE (window, GST_TYPE_VULKAN_WINDOW,
|
||||||
|
GstVulkanWindowPrivate);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -125,6 +141,10 @@ gst_vulkan_window_class_init (GstVulkanWindowClass * klass)
|
||||||
klass->open = GST_DEBUG_FUNCPTR (gst_vulkan_window_default_open);
|
klass->open = GST_DEBUG_FUNCPTR (gst_vulkan_window_default_open);
|
||||||
klass->close = GST_DEBUG_FUNCPTR (gst_vulkan_window_default_close);
|
klass->close = GST_DEBUG_FUNCPTR (gst_vulkan_window_default_close);
|
||||||
|
|
||||||
|
gst_vulkan_window_signals[SIGNAL_CLOSE] =
|
||||||
|
g_signal_new ("close", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0,
|
||||||
|
(GSignalAccumulator) _accum_logical_and, NULL, NULL, G_TYPE_BOOLEAN, 0);
|
||||||
|
|
||||||
G_OBJECT_CLASS (klass)->finalize = gst_vulkan_window_finalize;
|
G_OBJECT_CLASS (klass)->finalize = gst_vulkan_window_finalize;
|
||||||
|
|
||||||
_init_debug ();
|
_init_debug ();
|
||||||
|
@ -136,7 +156,7 @@ gst_vulkan_window_class_init (GstVulkanWindowClass * klass)
|
||||||
*
|
*
|
||||||
* Returns: (transfer full): a new #GstVulkanWindow using @display's connection
|
* Returns: (transfer full): a new #GstVulkanWindow using @display's connection
|
||||||
*
|
*
|
||||||
* Since: 1.4
|
* Since: 1.10
|
||||||
*/
|
*/
|
||||||
GstVulkanWindow *
|
GstVulkanWindow *
|
||||||
gst_vulkan_window_new (GstVulkanDisplay * display)
|
gst_vulkan_window_new (GstVulkanDisplay * display)
|
||||||
|
@ -217,12 +237,27 @@ void
|
||||||
gst_vulkan_window_close (GstVulkanWindow * window)
|
gst_vulkan_window_close (GstVulkanWindow * window)
|
||||||
{
|
{
|
||||||
GstVulkanWindowClass *klass;
|
GstVulkanWindowClass *klass;
|
||||||
|
gboolean to_close;
|
||||||
|
|
||||||
g_return_if_fail (GST_IS_VULKAN_WINDOW (window));
|
g_return_if_fail (GST_IS_VULKAN_WINDOW (window));
|
||||||
klass = GST_VULKAN_WINDOW_GET_CLASS (window);
|
klass = GST_VULKAN_WINDOW_GET_CLASS (window);
|
||||||
g_return_if_fail (klass->close != NULL);
|
g_return_if_fail (klass->close != NULL);
|
||||||
|
|
||||||
return klass->close (window);
|
g_signal_emit (window, gst_vulkan_window_signals[SIGNAL_CLOSE], 0, &to_close);
|
||||||
|
|
||||||
|
if (to_close)
|
||||||
|
klass->close (window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_vulkan_window_resize (GstVulkanWindow * window, gint width, gint height)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GST_IS_VULKAN_WINDOW (window));
|
||||||
|
|
||||||
|
window->priv->surface_width = width;
|
||||||
|
window->priv->surface_height = height;
|
||||||
|
|
||||||
|
/* XXX: possibly queue a resize/redraw */
|
||||||
}
|
}
|
||||||
|
|
||||||
GType gst_vulkan_dummy_window_get_type (void);
|
GType gst_vulkan_dummy_window_get_type (void);
|
||||||
|
|
|
@ -95,6 +95,8 @@ gpointer gst_vulkan_window_get_platform_handle (GstVulkanWindow *wi
|
||||||
gboolean gst_vulkan_window_open (GstVulkanWindow * window, GError ** error);
|
gboolean gst_vulkan_window_open (GstVulkanWindow * window, GError ** error);
|
||||||
void gst_vulkan_window_close (GstVulkanWindow * window);
|
void gst_vulkan_window_close (GstVulkanWindow * window);
|
||||||
|
|
||||||
|
void gst_vulkan_window_resize (GstVulkanWindow * window, gint width, gint height);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GST_VULKAN_WINDOW_H__ */
|
#endif /* __GST_VULKAN_WINDOW_H__ */
|
||||||
|
|
|
@ -61,17 +61,11 @@ gst_vulkan_display_xcb_finalize (GObject * object)
|
||||||
{
|
{
|
||||||
GstVulkanDisplayXCB *display_xcb = GST_VULKAN_DISPLAY_XCB (object);
|
GstVulkanDisplayXCB *display_xcb = GST_VULKAN_DISPLAY_XCB (object);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (gst_vulkan_display_xcb_parent_class)->finalize (object);
|
||||||
|
|
||||||
if (!display_xcb->foreign_display && display_xcb->platform_handle.connection)
|
if (!display_xcb->foreign_display && display_xcb->platform_handle.connection)
|
||||||
xcb_disconnect (display_xcb->platform_handle.connection);
|
xcb_disconnect (display_xcb->platform_handle.connection);
|
||||||
display_xcb->platform_handle.connection = NULL;
|
display_xcb->platform_handle.connection = NULL;
|
||||||
|
|
||||||
if (display_xcb->event_source) {
|
|
||||||
g_source_destroy (display_xcb->event_source);
|
|
||||||
g_source_unref (display_xcb->event_source);
|
|
||||||
}
|
|
||||||
display_xcb->event_source = NULL;
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (gst_vulkan_display_xcb_parent_class)->finalize (object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static xcb_screen_t *
|
static xcb_screen_t *
|
||||||
|
@ -106,25 +100,23 @@ gst_vulkan_display_xcb_new (const gchar * name)
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_GET (gst_vulkan_display_debug, "gldisplay");
|
GST_DEBUG_CATEGORY_GET (gst_vulkan_display_debug, "gldisplay");
|
||||||
|
|
||||||
ret = g_object_new (GST_TYPE_VULKAN_DISPLAY_XCB, NULL);
|
connection = xcb_connect (NULL, &screen_no);
|
||||||
|
|
||||||
ret->platform_handle.connection = connection = xcb_connect (NULL, &screen_no);
|
|
||||||
if (connection == NULL || xcb_connection_has_error (connection)) {
|
if (connection == NULL || xcb_connection_has_error (connection)) {
|
||||||
GST_ERROR_OBJECT (ret,
|
GST_ERROR ("Failed to open XCB display connection with name, \'%s\'", name);
|
||||||
"Failed to open XCB display connection with name, \'%s\'", name);
|
|
||||||
gst_object_unref (ret);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret->screen = _get_screen_from_connection (connection, screen_no);
|
ret = gst_vulkan_display_xcb_new_with_connection (connection, screen_no);
|
||||||
ret->platform_handle.root = ret->screen->root;
|
GST_VULKAN_DISPLAY (ret)->event_source = xcb_event_source_new (ret);
|
||||||
ret->event_source = xcb_event_source_new (ret);
|
g_source_attach (GST_VULKAN_DISPLAY (ret)->event_source,
|
||||||
|
GST_VULKAN_DISPLAY (ret)->main_context);
|
||||||
|
ret->foreign_display = FALSE;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_vulkan_display_xcb_new_with_display:
|
* gst_vulkan_display_xcb_new_with_connection:
|
||||||
* @display: an existing, xcb display
|
* @display: an existing, xcb display
|
||||||
*
|
*
|
||||||
* Creates a new display connection from a XCB Display.
|
* Creates a new display connection from a XCB Display.
|
||||||
|
|
|
@ -166,7 +166,9 @@ gst_vulkan_window_xcb_create_window (GstVulkanWindowXCB * window_xcb)
|
||||||
|
|
||||||
value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
|
value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
|
||||||
value_list[0] = screen->black_pixel;
|
value_list[0] = screen->black_pixel;
|
||||||
value_list[1] = XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_EXPOSURE;
|
value_list[1] =
|
||||||
|
XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_EXPOSURE |
|
||||||
|
XCB_EVENT_MASK_STRUCTURE_NOTIFY;
|
||||||
|
|
||||||
xcb_create_window (connection, XCB_COPY_FROM_PARENT, window_xcb->win_id,
|
xcb_create_window (connection, XCB_COPY_FROM_PARENT, window_xcb->win_id,
|
||||||
root_window, x, y, width, height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
|
root_window, x, y, width, height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
|
||||||
|
|
|
@ -82,29 +82,38 @@ _xcb_handle_event (GstVulkanDisplayXCB * display_xcb)
|
||||||
|
|
||||||
window_xcb =
|
window_xcb =
|
||||||
_find_window_from_xcb_window (display_xcb, client_event->window);
|
_find_window_from_xcb_window (display_xcb, client_event->window);
|
||||||
/* TODO: actually quit */
|
|
||||||
ret = FALSE;
|
if (window_xcb) {
|
||||||
#if 0
|
GST_INFO_OBJECT (window_xcb, "Close requested");
|
||||||
if (display->close)
|
|
||||||
display->close (display->close_data);
|
gst_vulkan_window_close (GST_VULKAN_WINDOW (window_xcb));
|
||||||
#endif
|
gst_vulkan_display_remove_window (GST_VULKAN_DISPLAY (display_xcb),
|
||||||
gst_object_unref (window_xcb);
|
GST_VULKAN_WINDOW (window_xcb));
|
||||||
|
gst_object_unref (window_xcb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (reply);
|
g_free (reply);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if 0
|
case XCB_CONFIGURE_NOTIFY:{
|
||||||
case CreateNotify:
|
xcb_configure_notify_event_t *configure_event;
|
||||||
case ConfigureNotify:
|
GstVulkanWindowXCB *window_xcb;
|
||||||
#if 0
|
|
||||||
gst_vulkan_window_resize (window, event.xconfigure.width,
|
|
||||||
event.xconfigure.height);
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case DestroyNotify:
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
configure_event = (xcb_configure_notify_event_t *) event;
|
||||||
|
window_xcb =
|
||||||
|
_find_window_from_xcb_window (display_xcb, configure_event->window);
|
||||||
|
|
||||||
|
if (window_xcb) {
|
||||||
|
gst_vulkan_window_resize (GST_VULKAN_WINDOW (window_xcb),
|
||||||
|
configure_event->width, configure_event->height);
|
||||||
|
|
||||||
|
gst_object_unref (window_xcb);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
case Expose:
|
case Expose:
|
||||||
/* non-zero means that other Expose follows
|
/* non-zero means that other Expose follows
|
||||||
* so just wait for the last one
|
* so just wait for the last one
|
||||||
|
@ -180,6 +189,8 @@ _xcb_handle_event (GstVulkanDisplayXCB * display_xcb)
|
||||||
GST_DEBUG ("unhandled XCB type: %u", event_code);
|
GST_DEBUG ("unhandled XCB type: %u", event_code);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_free (event);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in a new issue