vkutils: move object-specific context queries to their respective files

vkutils now just contains some utility functions to further simplify retrieving
multiple objects.
This commit is contained in:
Matthew Waters 2016-02-11 01:31:14 +11:00
parent d1d8a365a2
commit 5617b0904b
10 changed files with 324 additions and 145 deletions

View file

@ -40,11 +40,13 @@ static const char *device_validation_layers[] = {
#define GST_CAT_DEFAULT gst_vulkan_device_debug
GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT);
#define gst_vulkan_device_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstVulkanDevice, gst_vulkan_device, GST_TYPE_OBJECT,
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "vulkandevice", 0,
"Vulkan Device"));
"Vulkan Device");
GST_DEBUG_CATEGORY_GET (GST_CAT_CONTEXT, "GST_CONTEXT"));
static void gst_vulkan_device_finalize (GObject * object);
@ -402,3 +404,123 @@ gst_vulkan_device_create_cmd_buffer (GstVulkanDevice * device,
return TRUE;
}
/**
* gst_context_set_vulkan_device:
* @context: a #GstContext
* @device: a #GstVulkanDevice
*
* Sets @device on @context
*
* Since: 1.10
*/
void
gst_context_set_vulkan_device (GstContext * context, GstVulkanDevice * device)
{
GstStructure *s;
g_return_if_fail (context != NULL);
g_return_if_fail (gst_context_is_writable (context));
if (device)
GST_CAT_LOG (GST_CAT_CONTEXT,
"setting GstVulkanDevice(%" GST_PTR_FORMAT ") on context(%"
GST_PTR_FORMAT ")", device, context);
s = gst_context_writable_structure (context);
gst_structure_set (s, GST_VULKAN_DEVICE_CONTEXT_TYPE_STR,
GST_TYPE_VULKAN_DEVICE, device, NULL);
}
/**
* gst_context_get_vulkan_device:
* @context: a #GstContext
* @device: resulting #GstVulkanDevice
*
* Returns: Whether @device was in @context
*
* Since: 1.10
*/
gboolean
gst_context_get_vulkan_device (GstContext * context, GstVulkanDevice ** device)
{
const GstStructure *s;
gboolean ret;
g_return_val_if_fail (device != NULL, FALSE);
g_return_val_if_fail (context != NULL, FALSE);
s = gst_context_get_structure (context);
ret = gst_structure_get (s, GST_VULKAN_DEVICE_CONTEXT_TYPE_STR,
GST_TYPE_VULKAN_DEVICE, device, NULL);
GST_CAT_LOG (GST_CAT_CONTEXT, "got GstVulkanDevice(%" GST_PTR_FORMAT
") from context(%" GST_PTR_FORMAT ")", *device, context);
return ret;
}
gboolean
gst_vulkan_device_handle_context_query (GstElement * element, GstQuery * query,
GstVulkanDevice ** device)
{
gboolean res = FALSE;
const gchar *context_type;
GstContext *context, *old_context;
g_return_val_if_fail (element != NULL, FALSE);
g_return_val_if_fail (query != NULL, FALSE);
g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT, FALSE);
g_return_val_if_fail (device != NULL, FALSE);
gst_query_parse_context_type (query, &context_type);
if (g_strcmp0 (context_type, GST_VULKAN_DEVICE_CONTEXT_TYPE_STR) == 0) {
gst_query_parse_context (query, &old_context);
if (old_context)
context = gst_context_copy (old_context);
else
context = gst_context_new (GST_VULKAN_DEVICE_CONTEXT_TYPE_STR, TRUE);
gst_context_set_vulkan_device (context, *device);
gst_query_set_context (query, context);
gst_context_unref (context);
res = *device != NULL;
}
return res;
}
gboolean
gst_vulkan_device_run_context_query (GstElement * element,
GstVulkanDevice ** device)
{
GstQuery *query;
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
g_return_val_if_fail (device != NULL, FALSE);
if (*device && GST_IS_VULKAN_DEVICE (*device))
return TRUE;
if ((query =
gst_vulkan_local_context_query (element,
GST_VULKAN_DEVICE_CONTEXT_TYPE_STR, FALSE))) {
GstContext *context;
gst_query_parse_context (query, &context);
if (context)
gst_context_get_vulkan_device (context, device);
}
GST_DEBUG_OBJECT (element, "found device %p", *device);
gst_query_unref (query);
if (*device)
return TRUE;
return FALSE;
}

View file

@ -34,6 +34,8 @@ G_BEGIN_DECLS
#define GST_VULKAN_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_TYPE_VULKAN_DEVICE, GstVulkanDeviceClass))
GType gst_vulkan_device_get_type (void);
#define GST_VULKAN_DEVICE_CONTEXT_TYPE_STR "gst.vulkan.device"
struct _GstVulkanDevice
{
GstObject parent;
@ -77,6 +79,16 @@ gboolean gst_vulkan_device_create_cmd_buffer (GstVulkanDevice * d
VkCommandBuffer * cmd,
GError ** error);
void gst_context_set_vulkan_device (GstContext * context,
GstVulkanDevice * device);
gboolean gst_context_get_vulkan_device (GstContext * context,
GstVulkanDevice ** device);
gboolean gst_vulkan_device_handle_context_query (GstElement * element,
GstQuery * query,
GstVulkanDevice ** device);
gboolean gst_vulkan_device_run_context_query (GstElement * element,
GstVulkanDevice ** device);
G_END_DECLS
#endif /* _VK_DEVICE_H_ */

View file

@ -410,3 +410,57 @@ gst_vulkan_display_type_to_extension_string (GstVulkanDisplayType type)
return NULL;
}
gboolean
gst_vulkan_display_handle_context_query (GstElement * element, GstQuery * query,
GstVulkanDisplay ** display)
{
gboolean res = FALSE;
const gchar *context_type;
GstContext *context, *old_context;
g_return_val_if_fail (element != NULL, FALSE);
g_return_val_if_fail (query != NULL, FALSE);
g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT, FALSE);
g_return_val_if_fail (display != NULL, FALSE);
gst_query_parse_context_type (query, &context_type);
if (g_strcmp0 (context_type, GST_VULKAN_DISPLAY_CONTEXT_TYPE_STR) == 0) {
gst_query_parse_context (query, &old_context);
if (old_context)
context = gst_context_copy (old_context);
else
context = gst_context_new (GST_VULKAN_DISPLAY_CONTEXT_TYPE_STR, TRUE);
gst_context_set_vulkan_display (context, *display);
gst_query_set_context (query, context);
gst_context_unref (context);
res = *display != NULL;
}
return res;
}
gboolean
gst_vulkan_display_run_context_query (GstElement * element,
GstVulkanDisplay ** display)
{
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
g_return_val_if_fail (display != NULL, FALSE);
if (*display && GST_IS_VULKAN_DISPLAY (*display))
return TRUE;
gst_vulkan_global_context_query (element,
GST_VULKAN_DISPLAY_CONTEXT_TYPE_STR);
GST_DEBUG_OBJECT (element, "found display %p", *display);
if (*display)
return TRUE;
return FALSE;
}

View file

@ -101,6 +101,11 @@ gboolean gst_context_get_vulkan_display (GstContext
GstVulkanDisplay ** display);
void gst_context_set_vulkan_display (GstContext * context,
GstVulkanDisplay * display);
gboolean gst_vulkan_display_handle_context_query (GstElement * element,
GstQuery * query,
GstVulkanDisplay ** display);
gboolean gst_vulkan_display_run_context_query (GstElement * element,
GstVulkanDisplay ** display);
/* GstVulkanWindow usage only */
gboolean gst_vulkan_display_remove_window (GstVulkanDisplay * display, GstVulkanWindow * window);

View file

@ -43,7 +43,7 @@ static const char *instance_validation_layers[] = {
#define GST_CAT_DEFAULT gst_vulkan_instance_debug
GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
GST_DEBUG_CATEGORY (GST_VULKAN_DEBUG_CAT);
GST_DEBUG_CATEGORY (GST_CAT_CONTEXT);
GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT);
enum
{
@ -486,3 +486,57 @@ gst_context_get_vulkan_instance (GstContext * context,
return ret;
}
gboolean
gst_vulkan_instance_handle_context_query (GstElement * element,
GstQuery * query, GstVulkanInstance ** instance)
{
gboolean res = FALSE;
const gchar *context_type;
GstContext *context, *old_context;
g_return_val_if_fail (element != NULL, FALSE);
g_return_val_if_fail (query != NULL, FALSE);
g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT, FALSE);
g_return_val_if_fail (instance != NULL, FALSE);
gst_query_parse_context_type (query, &context_type);
if (g_strcmp0 (context_type, GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR) == 0) {
gst_query_parse_context (query, &old_context);
if (old_context)
context = gst_context_copy (old_context);
else
context = gst_context_new (GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR, TRUE);
gst_context_set_vulkan_instance (context, *instance);
gst_query_set_context (query, context);
gst_context_unref (context);
res = *instance != NULL;
}
return res;
}
gboolean
gst_vulkan_instance_run_context_query (GstElement * element,
GstVulkanInstance ** instance)
{
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
g_return_val_if_fail (instance != NULL, FALSE);
if (*instance && GST_IS_VULKAN_INSTANCE (*instance))
return TRUE;
gst_vulkan_global_context_query (element,
GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR);
GST_DEBUG_OBJECT (element, "found instance %p", *instance);
if (*instance)
return TRUE;
return FALSE;
}

View file

@ -56,20 +56,25 @@ struct _GstVulkanInstanceClass
GstObjectClass parent_class;
};
GstVulkanInstance * gst_vulkan_instance_new (void);
gboolean gst_vulkan_instance_open (GstVulkanInstance * instance,
GError ** error);
GstVulkanInstance * gst_vulkan_instance_new (void);
gboolean gst_vulkan_instance_open (GstVulkanInstance * instance,
GError ** error);
gpointer gst_vulkan_instance_get_proc_address (GstVulkanInstance * instance,
const gchar * name);
gpointer gst_vulkan_instance_get_proc_address (GstVulkanInstance * instance,
const gchar * name);
GstVulkanDevice * gst_vulkan_instance_create_device (GstVulkanInstance * instance,
GError ** error);
GstVulkanDevice * gst_vulkan_instance_create_device (GstVulkanInstance * instance,
GError ** error);
void gst_context_set_vulkan_instance (GstContext * context,
GstVulkanInstance * instance);
gboolean gst_context_get_vulkan_instance (GstContext * context,
GstVulkanInstance ** instance);
void gst_context_set_vulkan_instance (GstContext * context,
GstVulkanInstance * instance);
gboolean gst_context_get_vulkan_instance (GstContext * context,
GstVulkanInstance ** instance);
gboolean gst_vulkan_instance_handle_context_query (GstElement * element,
GstQuery * query,
GstVulkanInstance ** instance);
gboolean gst_vulkan_instance_run_context_query (GstElement * element,
GstVulkanInstance ** instance);
G_END_DECLS

View file

@ -205,15 +205,13 @@ static gboolean
gst_vulkan_sink_query (GstBaseSink * bsink, GstQuery * query)
{
GstVulkanSink *vk_sink = GST_VULKAN_SINK (bsink);
gboolean res = FALSE;
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_CONTEXT:{
res = gst_vulkan_handle_context_query (GST_ELEMENT (vk_sink), query,
&vk_sink->display, &vk_sink->instance, &vk_sink->device);
if (gst_vulkan_handle_context_query (GST_ELEMENT (vk_sink), query,
&vk_sink->display, &vk_sink->instance, &vk_sink->device))
return TRUE;
if (res)
return res;
break;
}
default:

View file

@ -583,47 +583,6 @@ gst_vulkan_upload_set_context (GstElement * element, GstContext * context)
GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
}
static gboolean
_find_vulkan_device (GstVulkanUpload * upload)
{
/* Requires the instance to exist */
GstQuery *query;
GstContext *context;
const GstStructure *s;
if (upload->device)
return TRUE;
query = gst_query_new_context ("gst.vulkan.device");
if (!upload->device
&& gst_vulkan_run_query (GST_ELEMENT (upload), query, GST_PAD_SRC)) {
gst_query_parse_context (query, &context);
if (context) {
s = gst_context_get_structure (context);
gst_structure_get (s, "device", GST_TYPE_VULKAN_DEVICE, &upload->device,
NULL);
}
}
if (!upload->device
&& gst_vulkan_run_query (GST_ELEMENT (upload), query, GST_PAD_SINK)) {
gst_query_parse_context (query, &context);
if (context) {
s = gst_context_get_structure (context);
gst_structure_get (s, "device", GST_TYPE_VULKAN_DEVICE, &upload->device,
NULL);
}
}
GST_DEBUG_OBJECT (upload, "found device %p", upload->device);
gst_query_unref (query);
if (upload->device)
return TRUE;
return FALSE;
}
static GstStateChangeReturn
gst_vulkan_upload_change_state (GstElement * element, GstStateChange transition)
{
@ -644,7 +603,8 @@ gst_vulkan_upload_change_state (GstElement * element, GstStateChange transition)
("Failed to retreive vulkan instance/display"), (NULL));
return GST_STATE_CHANGE_FAILURE;
}
if (!_find_vulkan_device (vk_upload)) {
if (!gst_vulkan_device_run_context_query (GST_ELEMENT (vk_upload),
&vk_upload->device)) {
GST_ELEMENT_ERROR (vk_upload, RESOURCE, NOT_FOUND,
("Failed to retreive vulkan device"), (NULL));
return GST_STATE_CHANGE_FAILURE;

View file

@ -106,8 +106,39 @@ gst_vulkan_run_query (GstElement * element, GstQuery * query,
return g_value_get_boolean (&res);
}
static void
_vk_gst_context_query (GstElement * element, const gchar * display_type)
void
gst_vulkan_global_context_query (GstElement * element,
const gchar * context_type)
{
GstQuery *query;
GstMessage *msg;
if ((query = gst_vulkan_local_context_query (element, context_type, TRUE))) {
gst_query_unref (query);
return;
}
/* 3) Post a GST_MESSAGE_NEED_CONTEXT message on the bus with
* the required context type and afterwards check if a
* usable context was set now as in 1). The message could
* be handled by the parent bins of the element and the
* application.
*/
GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element,
"posting need context message");
msg = gst_message_new_need_context (GST_OBJECT_CAST (element), context_type);
gst_element_post_message (element, msg);
/*
* Whomever responds to the need-context message performs a
* GstElement::set_context() with the required context in which the element
* is required to update the display_ptr or call gst_vulkan_handle_set_context().
*/
}
GstQuery *
gst_vulkan_local_context_query (GstElement * element,
const gchar * context_type, gboolean set_context)
{
GstQuery *query;
GstContext *ctxt;
@ -118,47 +149,33 @@ _vk_gst_context_query (GstElement * element, const gchar * display_type)
* check if downstream already has a context of the specific type
* 2b) Query upstream as above.
*/
query = gst_query_new_context (display_type);
query = gst_query_new_context (context_type);
if (gst_vulkan_run_query (element, query, GST_PAD_SRC)) {
gst_query_parse_context (query, &ctxt);
GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element,
"found context (%p) in downstream query", ctxt);
gst_element_set_context (element, ctxt);
if (set_context)
gst_element_set_context (element, ctxt);
} else if (gst_vulkan_run_query (element, query, GST_PAD_SINK)) {
gst_query_parse_context (query, &ctxt);
GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element,
"found context (%p) in upstream query", ctxt);
gst_element_set_context (element, ctxt);
if (set_context)
gst_element_set_context (element, ctxt);
} else {
/* 3) Post a GST_MESSAGE_NEED_CONTEXT message on the bus with
* the required context type and afterwards check if a
* usable context was set now as in 1). The message could
* be handled by the parent bins of the element and the
* application.
*/
GstMessage *msg;
GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element,
"posting need context message");
msg = gst_message_new_need_context (GST_OBJECT_CAST (element),
display_type);
gst_element_post_message (element, msg);
gst_query_unref (query);
query = NULL;
}
/*
* Whomever responds to the need-context message performs a
* GstElement::set_context() with the required context in which the element
* is required to update the display_ptr or call gst_vulkan_handle_set_context().
*/
gst_query_unref (query);
return query;
}
static void
_vk_display_context_query (GstElement * element,
GstVulkanDisplay ** display_ptr)
{
_vk_gst_context_query (element, GST_VULKAN_DISPLAY_CONTEXT_TYPE_STR);
gst_vulkan_global_context_query (element,
GST_VULKAN_DISPLAY_CONTEXT_TYPE_STR);
}
/* 4) Create a context by itself and post a GST_MESSAGE_HAVE_CONTEXT
@ -197,7 +214,8 @@ gst_vulkan_ensure_element_data (gpointer element,
if (!*instance_ptr) {
GError *error = NULL;
_vk_gst_context_query (element, GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR);
gst_vulkan_global_context_query (element,
GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR);
/* Neighbour found and it updated the display */
if (!*instance_ptr) {
@ -295,63 +313,12 @@ gst_vulkan_handle_context_query (GstElement * element, GstQuery * query,
GstVulkanDisplay ** display, GstVulkanInstance ** instance,
GstVulkanDevice ** device)
{
gboolean res = FALSE;
const gchar *context_type;
GstContext *context, *old_context;
if (gst_vulkan_display_handle_context_query (element, query, display))
return TRUE;
if (gst_vulkan_instance_handle_context_query (element, query, instance))
return TRUE;
if (gst_vulkan_device_handle_context_query (element, query, device))
return TRUE;
g_return_val_if_fail (element != NULL, FALSE);
g_return_val_if_fail (query != NULL, FALSE);
g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT, FALSE);
g_return_val_if_fail (display != NULL, FALSE);
g_return_val_if_fail (instance != NULL, FALSE);
g_return_val_if_fail (device != NULL, FALSE);
gst_query_parse_context_type (query, &context_type);
if (g_strcmp0 (context_type, GST_VULKAN_DISPLAY_CONTEXT_TYPE_STR) == 0) {
gst_query_parse_context (query, &old_context);
if (old_context)
context = gst_context_copy (old_context);
else
context = gst_context_new (GST_VULKAN_DISPLAY_CONTEXT_TYPE_STR, TRUE);
gst_context_set_vulkan_display (context, *display);
gst_query_set_context (query, context);
gst_context_unref (context);
res = *display != NULL;
} else if (g_strcmp0 (context_type,
GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR) == 0) {
gst_query_parse_context (query, &old_context);
if (old_context)
context = gst_context_copy (old_context);
else
context = gst_context_new (GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR, TRUE);
gst_context_set_vulkan_instance (context, *instance);
gst_query_set_context (query, context);
gst_context_unref (context);
res = *instance != NULL;
} else if (g_strcmp0 (context_type, "gst.vulkan.device") == 0) {
GstStructure *s;
gst_query_parse_context (query, &old_context);
if (old_context)
context = gst_context_copy (old_context);
else
context = gst_context_new ("gst.vulkan.device", TRUE);
s = gst_context_writable_structure (context);
gst_structure_set (s, "device", GST_TYPE_VULKAN_DEVICE, *device, NULL);
gst_query_set_context (query, context);
gst_context_unref (context);
res = *instance != NULL;
}
return res;
return FALSE;
}

View file

@ -32,6 +32,8 @@ gboolean gst_vulkan_handle_set_context (GstElement * element, GstContext * conte
gboolean gst_vulkan_handle_context_query (GstElement * element, GstQuery * query,
GstVulkanDisplay ** display, GstVulkanInstance ** instance, GstVulkanDevice ** device);
void gst_vulkan_global_context_query (GstElement * element, const gchar * context_type);
GstQuery * gst_vulkan_local_context_query (GstElement * element, const gchar * context_type, gboolean set_context);
gboolean gst_vulkan_run_query (GstElement * element,
GstQuery * query, GstPadDirection direction);