3 * Copyright (C) 2019 Matthew Waters <matthew@centricular.com>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
27 #include <gst/vulkan/vulkan.h>
29 #include "gstvkwindow_android.h"
30 #include "gstvkdisplay_android.h"
32 #define GET_PRIV(o) gst_vulkan_window_android_get_instance_private (o)
34 #define GST_CAT_DEFAULT gst_vulkan_window_android_debug
35 GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
40 static gsize _init = 0;
42 if (g_once_init_enter (&_init)) {
43 GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "vulkanwindowandroid", 0,
44 "Vulkan Android Window");
45 g_once_init_leave (&_init, 1);
54 struct _GstVulkanWindowAndroidPrivate
56 struct ANativeWindow *internal_window;
57 gint window_width, window_height;
60 gint preferred_height;
63 #define gst_vulkan_window_android_parent_class parent_class
64 G_DEFINE_TYPE_WITH_CODE (GstVulkanWindowAndroid, gst_vulkan_window_android,
65 GST_TYPE_VULKAN_WINDOW,
66 G_ADD_PRIVATE (GstVulkanWindowAndroid) _init_debug ());
68 static VkSurfaceKHR gst_vulkan_window_android_get_surface (GstVulkanWindow *
69 window, GError ** error);
71 gst_vulkan_window_android_get_presentation_support (GstVulkanWindow * window,
72 GstVulkanDevice * device, guint32 queue_family_idx);
73 static gboolean gst_vulkan_window_android_open (GstVulkanWindow * window,
75 static void gst_vulkan_window_android_close (GstVulkanWindow * window);
76 static void gst_vulkan_window_android_set_window_handle (GstVulkanWindow *
77 window, guintptr window_handle);
80 gst_vulkan_window_android_class_init (GstVulkanWindowAndroidClass * klass)
82 GstVulkanWindowClass *window_class = (GstVulkanWindowClass *) klass;
84 window_class->open = GST_DEBUG_FUNCPTR (gst_vulkan_window_android_open);
85 window_class->close = GST_DEBUG_FUNCPTR (gst_vulkan_window_android_close);
86 window_class->get_surface = gst_vulkan_window_android_get_surface;
87 window_class->get_presentation_support =
88 gst_vulkan_window_android_get_presentation_support;
89 window_class->set_window_handle = gst_vulkan_window_android_set_window_handle;
93 gst_vulkan_window_android_init (GstVulkanWindowAndroid * window)
95 GstVulkanWindowAndroidPrivate *priv = GET_PRIV (window);
97 priv->preferred_width = 320;
98 priv->preferred_height = 240;
101 /* Must be called in the gl thread */
102 GstVulkanWindowAndroid *
103 gst_vulkan_window_android_new (GstVulkanDisplay * display)
105 GstVulkanWindowAndroid *window;
109 if ((gst_vulkan_display_get_handle_type (display) &
110 GST_VULKAN_DISPLAY_TYPE_ANDROID)
111 == GST_VULKAN_DISPLAY_TYPE_NONE) {
112 GST_INFO ("Wrong display type %u for this window type %u", display->type,
113 GST_VULKAN_DISPLAY_TYPE_ANDROID);
117 window = g_object_new (GST_TYPE_VULKAN_WINDOW_ANDROID, NULL);
118 gst_object_ref_sink (window);
124 gst_vulkan_window_android_create_window (GstVulkanWindowAndroid *
127 GstVulkanWindowAndroidPrivate *priv = GET_PRIV (window_android);
129 if (!priv->internal_window) {
130 GST_WARNING_OBJECT (window_android, "No ANativeWindow provided");
138 gst_vulkan_window_android_get_surface (GstVulkanWindow * window,
141 GstVulkanWindowAndroid *window_android = GST_VULKAN_WINDOW_ANDROID (window);
142 GstVulkanWindowAndroidPrivate *priv = GET_PRIV (window_android);
143 VkAndroidSurfaceCreateInfoKHR info = { 0, };
147 if (!priv->internal_window) {
148 g_set_error_literal (error, GST_VULKAN_ERROR,
149 VK_ERROR_INITIALIZATION_FAILED,
150 "No layer to retrieve surface for. Has create_window() been called?");
154 info.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
157 info.window = priv->internal_window;
159 if (!window_android->CreateAndroidSurface)
160 window_android->CreateAndroidSurface =
161 gst_vulkan_instance_get_proc_address (window->display->instance,
162 "vkCreateAndroidSurfaceKHR");
163 if (!window_android->CreateAndroidSurface) {
164 g_set_error_literal (error, GST_VULKAN_ERROR, VK_ERROR_FEATURE_NOT_PRESENT,
165 "Could not retrieve \"vkCreateAndroidSurfaceKHR\" function pointer");
170 window_android->CreateAndroidSurface (window->display->instance->instance,
172 if (gst_vulkan_error_to_g_error (err, error, "vkCreateAndroidSurfaceKHR") < 0)
179 gst_vulkan_window_android_get_presentation_support (GstVulkanWindow * window,
180 GstVulkanDevice * device, guint32 queue_family_idx)
186 gst_vulkan_window_android_open (GstVulkanWindow * window, GError ** error)
188 GstVulkanWindowAndroid *window_android = GST_VULKAN_WINDOW_ANDROID (window);
190 if (!GST_VULKAN_WINDOW_CLASS (parent_class)->open (window, error))
193 return gst_vulkan_window_android_create_window (window_android);
197 gst_vulkan_window_android_close (GstVulkanWindow * window)
199 GST_VULKAN_WINDOW_CLASS (parent_class)->close (window);
203 gst_vulkan_window_android_set_window_handle (GstVulkanWindow * window,
204 guintptr window_handle)
206 GstVulkanWindowAndroid *window_android = GST_VULKAN_WINDOW_ANDROID (window);
207 GstVulkanWindowAndroidPrivate *priv = GET_PRIV (window_android);
208 struct ANativeWindow *native_window = (struct ANativeWindow *) window_handle;
210 g_return_if_fail (native_window != NULL);
212 if (priv->internal_window && priv->internal_window != native_window) {
213 GST_FIXME_OBJECT (window_android, "View changes are not implemented");
217 priv->internal_window = native_window;