summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2016-11-30 00:54:48 +0100
committerBenjamin Otte <otte@redhat.com>2016-12-09 18:35:51 +0100
commit325efe707827d0e0f11d849e950930537bf7f1fb (patch)
tree18113c06fd71b49716c059523288fdcb086e3fd4
parenta753f047df93b80949b06ed2e368a7de8f42c442 (diff)
downloadgtk+-325efe707827d0e0f11d849e950930537bf7f1fb.tar.gz
vulkan: Expose the swapchain images in public API
-rw-r--r--gdk/gdkvulkancontext.c90
-rw-r--r--gdk/gdkvulkancontext.h5
2 files changed, 90 insertions, 5 deletions
diff --git a/gdk/gdkvulkancontext.c b/gdk/gdkvulkancontext.c
index af485b4e79..03cbbfecd7 100644
--- a/gdk/gdkvulkancontext.c
+++ b/gdk/gdkvulkancontext.c
@@ -36,10 +36,21 @@ struct _GdkVulkanContextPrivate {
int swapchain_width, swapchain_height;
VkSwapchainKHR swapchain;
+
+ guint n_images;
+ VkImage *images;
+};
+
+enum {
+ IMAGES_UPDATED,
+
+ LAST_SIGNAL
};
G_DEFINE_QUARK (gdk-vulkan-error-quark, gdk_vulkan_error)
+static guint signals[LAST_SIGNAL] = { 0 };
+
static void gdk_vulkan_context_initable_init (GInitableIface *iface);
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GdkVulkanContext, gdk_vulkan_context, GDK_TYPE_DRAW_CONTEXT,
@@ -111,6 +122,9 @@ gdk_vulkan_context_dispose (GObject *gobject)
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
GdkDisplay *display;
+ g_clear_pointer (&priv->images, g_free);
+ priv->n_images = 0;
+
if (priv->swapchain != VK_NULL_HANDLE)
{
vkDestroySwapchainKHR (gdk_vulkan_context_get_device (context),
@@ -141,6 +155,23 @@ gdk_vulkan_context_class_init (GdkVulkanContextClass *klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->dispose = gdk_vulkan_context_dispose;
+
+ /**
+ * GdkVulkanContext::images-updated:
+ * @context: the object on which the signal is emitted
+ *
+ * This signal is emitted when the images managed by this context have
+ * changed. Usually this means that the swapchain had to be recreated,
+ * for example in response to a change of the window size.
+ */
+ signals[IMAGES_UPDATED] =
+ g_signal_new (g_intern_static_string ("images-updated"),
+ G_OBJECT_CLASS_TYPE (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
}
static void
@@ -158,11 +189,14 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
VkCompositeAlphaFlagBitsKHR composite_alpha;
VkSwapchainKHR new_swapchain;
VkResult res;
+ VkDevice device;
if (gdk_window_get_width (window) == priv->swapchain_width &&
gdk_window_get_height (window) == priv->swapchain_height)
return TRUE;
+ device = gdk_vulkan_context_get_device (context);
+
res = GDK_VK_CHECK (vkGetPhysicalDeviceSurfaceCapabilitiesKHR, gdk_vulkan_context_get_physical_device (context),
priv->surface,
&capabilities);
@@ -188,7 +222,7 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
composite_alpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
}
- res = GDK_VK_CHECK (vkCreateSwapchainKHR, gdk_vulkan_context_get_device (context),
+ res = GDK_VK_CHECK (vkCreateSwapchainKHR, device,
&(VkSwapchainCreateInfoKHR) {
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
.pNext = NULL,
@@ -215,15 +249,29 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
&new_swapchain);
if (priv->swapchain != VK_NULL_HANDLE)
- vkDestroySwapchainKHR (gdk_vulkan_context_get_device (context),
- priv->swapchain,
- NULL);
+ {
+ vkDestroySwapchainKHR (device,
+ priv->swapchain,
+ NULL);
+ g_clear_pointer (&priv->images, g_free);
+ priv->n_images = 0;
+ }
if (res == VK_SUCCESS)
{
priv->swapchain_width = gdk_window_get_width (window);
priv->swapchain_height = gdk_window_get_height (window);
priv->swapchain = new_swapchain;
+
+ GDK_VK_CHECK (vkGetSwapchainImagesKHR, device,
+ priv->swapchain,
+ &priv->n_images,
+ NULL);
+ priv->images = g_new (VkImage, priv->n_images);
+ GDK_VK_CHECK (vkGetSwapchainImagesKHR, device,
+ priv->swapchain,
+ &priv->n_images,
+ priv->images);
}
else
{
@@ -235,7 +283,9 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
return FALSE;
}
- return TRUE;
+ g_signal_emit (context, signals[IMAGES_UPDATED], 0);
+
+ return res == VK_SUCCESS;
}
static gboolean
@@ -367,6 +417,28 @@ gdk_vulkan_context_get_image_format (GdkVulkanContext *context)
return priv->image_format.format;
}
+guint
+gdk_vulkan_context_get_n_images (GdkVulkanContext *context)
+{
+ GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
+
+ g_return_val_if_fail (GDK_IS_VULKAN_CONTEXT (context), 0);
+
+ return priv->n_images;
+}
+
+VkImage
+gdk_vulkan_context_get_image (GdkVulkanContext *context,
+ guint id)
+{
+ GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
+
+ g_return_val_if_fail (GDK_IS_VULKAN_CONTEXT (context), VK_NULL_HANDLE);
+ g_return_val_if_fail (id < priv->n_images, VK_NULL_HANDLE);
+
+ return priv->images[id];
+}
+
static gboolean
gdk_display_create_vulkan_device (GdkDisplay *display,
GError **error)
@@ -672,6 +744,14 @@ gdk_display_unref_vulkan (GdkDisplay *display)
static void
gdk_vulkan_context_class_init (GdkVulkanContextClass *klass)
{
+ signals[IMAGES_UPDATED] =
+ g_signal_new (g_intern_static_string ("images-updated"),
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
}
static void
diff --git a/gdk/gdkvulkancontext.h b/gdk/gdkvulkancontext.h
index d4b078903b..2690048e85 100644
--- a/gdk/gdkvulkancontext.h
+++ b/gdk/gdkvulkancontext.h
@@ -63,6 +63,11 @@ GDK_AVAILABLE_IN_3_90
uint32_t gdk_vulkan_context_get_queue_family_index (GdkVulkanContext *context);
GDK_AVAILABLE_IN_3_90
VkFormat gdk_vulkan_context_get_image_format (GdkVulkanContext *context);
+GDK_AVAILABLE_IN_3_90
+guint gdk_vulkan_context_get_n_images (GdkVulkanContext *context);
+GDK_AVAILABLE_IN_3_90
+VkImage gdk_vulkan_context_get_image (GdkVulkanContext *context,
+ guint id);
#endif /* GDK_WINDOWING_VULKAN */