gl/display: provide a gst_gl_display_new_with_type()

Allows more fine-grained control over the exact display type that is
created.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/1154>
This commit is contained in:
Matthew Waters 2021-05-18 19:56:13 +10:00 committed by GStreamer Marge Bot
parent 87327110c2
commit f0eca69a14
3 changed files with 183 additions and 27 deletions

View file

@ -103,7 +103,13 @@ gst_gl_context_eagl_new (GstGLDisplay * display)
{
GstGLContextEagl *context;
/* there isn't actually a display type for eagl yet? */
if ((gst_gl_display_get_handle_type (display) & GST_GL_DISPLAY_TYPE_EAGL)
== GST_GL_DISPLAY_TYPE_NONE) {
GST_INFO ("Wrong display type %u for this window type %u", display->type,
GST_GL_DISPLAY_TYPE_EAGL);
return NULL;
}
context = g_object_new (GST_TYPE_GL_CONTEXT_EAGL, NULL);
gst_object_ref_sink (context);

View file

@ -265,18 +265,9 @@ gst_gl_display_finalize (GObject * object)
G_OBJECT_CLASS (gst_gl_display_parent_class)->finalize (object);
}
/**
* gst_gl_display_new:
*
* Returns: (transfer full): a new #GstGLDisplay
*
* Since: 1.4
*/
GstGLDisplay *
gst_gl_display_new (void)
static void
init_debug (void)
{
GstGLDisplay *display = NULL;
const gchar *user_choice, *platform_choice;
static gsize _init = 0;
if (g_once_init_enter (&_init)) {
@ -284,29 +275,106 @@ gst_gl_display_new (void)
"gldisplay element");
g_once_init_leave (&_init, 1);
}
}
static GstGLDisplayType
gst_gl_display_type_from_environment (void)
{
const char *env = g_getenv ("GST_GL_WINDOW");
const char *platform = g_getenv ("GST_GL_PLATFORM");
init_debug ();
user_choice = g_getenv ("GST_GL_WINDOW");
platform_choice = g_getenv ("GST_GL_PLATFORM");
GST_INFO ("creating a display, user choice:%s (platform: %s)",
GST_STR_NULL (user_choice), GST_STR_NULL (platform_choice));
GST_STR_NULL (env), GST_STR_NULL (platform));
if (!env && !platform)
return GST_GL_DISPLAY_TYPE_ANY;
if (env) {
if (g_strstr_len (env, 3, "x11")) {
return GST_GL_DISPLAY_TYPE_X11;
} else if (g_strstr_len (env, 7, "wayland")) {
return GST_GL_DISPLAY_TYPE_WAYLAND;
} else if (g_strstr_len (env, 5, "cocoa")) {
return GST_GL_DISPLAY_TYPE_COCOA;
} else if (g_strstr_len (env, 5, "win32")) {
return GST_GL_DISPLAY_TYPE_WIN32;
} else if (g_strstr_len (env, 8, "dispmanx")) {
return GST_GL_DISPLAY_TYPE_DISPMANX;
} else if (g_strstr_len (env, 3, "egl")) {
return GST_GL_DISPLAY_TYPE_EGL;
} else if (g_strstr_len (env, 6, "viv-fb")) {
return GST_GL_DISPLAY_TYPE_VIV_FB;
} else if (g_strstr_len (env, 3, "gbm")) {
return GST_GL_DISPLAY_TYPE_GBM;
} else if (g_strstr_len (env, 10, "egl-device")) {
return GST_GL_DISPLAY_TYPE_EGL_DEVICE;
} else if (g_strstr_len (env, 4, "eagl")) {
return GST_GL_DISPLAY_TYPE_EAGL;
} else if (g_strstr_len (env, 7, "android")) {
return GST_GL_DISPLAY_TYPE_EGL;
} else if (g_strstr_len (env, 4, "winrt")) {
return GST_GL_DISPLAY_TYPE_EGL;
}
}
if (platform && g_strstr_len (platform, 3, "egl")) {
return GST_GL_DISPLAY_TYPE_EGL;
}
return GST_GL_DISPLAY_TYPE_NONE;
}
static GstGLDisplay *
create_dummy_display (void)
{
GstGLDisplay *display = g_object_new (GST_TYPE_GL_DISPLAY, NULL);
return gst_object_ref_sink (display);
}
/**
* gst_gl_display_new_with_type:
* @type: #GstGLDisplayType
*
* Will always return a #GstGLDisplay of a single type. This differs from
* gst_gl_display_new() and the seemingly equivalent call
* gst_gl_display_new_with_type (GST_GL_DISPLAY_TYPE_ANY) in that the latter
* may return NULL.
*
* Returns: (transfer full) (nullable): a new #GstGLDisplay or %NULL if @type is
* not supported
*
* Since: 1.20
*/
GstGLDisplay *
gst_gl_display_new_with_type (GstGLDisplayType type)
{
GstGLDisplay *display = NULL;
GstGLDisplayType custom_new_types = 0;
init_debug ();
#if GST_GL_HAVE_WINDOW_COCOA
if (!display && (!user_choice || g_strstr_len (user_choice, 5, "cocoa"))) {
if (!display && (type & GST_GL_DISPLAY_TYPE_COCOA)) {
display = GST_GL_DISPLAY (gst_gl_display_cocoa_new ());
if (!display)
return NULL;
}
#endif
custom_new_types |= GST_GL_DISPLAY_TYPE_COCOA;
#if GST_GL_HAVE_WINDOW_WAYLAND
if (!display && (!user_choice || g_strstr_len (user_choice, 7, "wayland")))
if (!display && (type & GST_GL_DISPLAY_TYPE_WAYLAND))
display = GST_GL_DISPLAY (gst_gl_display_wayland_new (NULL));
#endif
custom_new_types |= GST_GL_DISPLAY_TYPE_WAYLAND;
#if GST_GL_HAVE_WINDOW_X11
if (!display && (!user_choice || g_strstr_len (user_choice, 3, "x11")))
if (!display && (type & GST_GL_DISPLAY_TYPE_X11))
display = GST_GL_DISPLAY (gst_gl_display_x11_new (NULL));
#endif
custom_new_types |= GST_GL_DISPLAY_TYPE_X11;
#if GST_GL_HAVE_WINDOW_VIV_FB
if (!display && (!user_choice || g_strstr_len (user_choice, 6, "viv-fb"))) {
if (!display && (GST_GL_DISPLAY_TYPE_VIV_FB)) {
const gchar *disp_idx_str = NULL;
gint disp_idx = 0;
disp_idx_str = g_getenv ("GST_GL_VIV_FB");
@ -318,27 +386,77 @@ gst_gl_display_new (void)
display = GST_GL_DISPLAY (gst_gl_display_viv_fb_new (disp_idx));
}
#endif
custom_new_types |= GST_GL_DISPLAY_TYPE_VIV_FB;
#if GST_GL_HAVE_WINDOW_GBM
if (!display && (!user_choice || g_strstr_len (user_choice, 3, "gbm"))) {
if (!display && (type & GST_GL_DISPLAY_TYPE_GBM)) {
display = GST_GL_DISPLAY (gst_gl_display_gbm_new ());
}
#endif
custom_new_types |= GST_GL_DISPLAY_TYPE_GBM;
#if GST_GL_HAVE_PLATFORM_EGL
if (!display && (user_choice && g_strstr_len (user_choice, 10, "egl-device"))) {
if (!display && (type == GST_GL_DISPLAY_TYPE_EGL_DEVICE)) {
display = GST_GL_DISPLAY (gst_gl_display_egl_device_new (0));
}
if (!display && (!platform_choice
|| g_strstr_len (platform_choice, 3, "egl"))) {
if (!display && (type & GST_GL_DISPLAY_TYPE_EGL)) {
display = GST_GL_DISPLAY (gst_gl_display_egl_new ());
}
#endif
custom_new_types |= GST_GL_DISPLAY_TYPE_EGL_DEVICE;
custom_new_types |= GST_GL_DISPLAY_TYPE_EGL;
custom_new_types |= GST_GL_DISPLAY_TYPE_DISPMANX;
custom_new_types |= GST_GL_DISPLAY_TYPE_WINRT;
custom_new_types |= GST_GL_DISPLAY_TYPE_ANDROID;
#if GST_GL_HAVE_WINDOW_WIN32 || GST_GL_HAVE_WINDOW_EAGL
if (!display) {
GST_INFO ("Could not create platform/winsys display. user specified %s "
"(platform: %s), creating dummy",
GST_STR_NULL (user_choice), GST_STR_NULL (platform_choice));
GstGLDisplayType create_type = 0;
if (type & GST_GL_DISPLAY_TYPE_WIN32)
create_type = GST_GL_DISPLAY_TYPE_WIN32;
else if (type & GST_GL_DISPLAY_TYPE_EAGL)
create_type = GST_GL_DISPLAY_TYPE_EAGL;
if (create_type) {
GST_INFO_OBJECT (display, "Creating display with type %u(0x%x)",
create_type, create_type);
display = create_dummy_display ();
display->type = create_type;
}
}
#endif
custom_new_types |= GST_GL_DISPLAY_TYPE_WIN32;
custom_new_types |= GST_GL_DISPLAY_TYPE_EAGL;
if (!display && type != GST_GL_DISPLAY_TYPE_ANY
&& type != GST_GL_DISPLAY_TYPE_NONE) {
/* remove all the display types that we know about */
type &= ~custom_new_types;
if (type && (type & (type - 1)) == 0) {
/* only create a dummy display if we only have a single type */
GST_INFO_OBJECT (display, "Creating dummy display with type %u(0x%x)",
type, type);
display = create_dummy_display ();
display->type = type;
}
}
return display;
}
/**
* gst_gl_display_new:
*
* Returns: (transfer full): a new #GstGLDisplay
*
* Since: 1.4
*/
GstGLDisplay *
gst_gl_display_new (void)
{
GstGLDisplayType env_choice = gst_gl_display_type_from_environment ();
GstGLDisplay *display = gst_gl_display_new_with_type (env_choice);
if (!display) {
display = g_object_new (GST_TYPE_GL_DISPLAY, NULL);
GST_INFO_OBJECT (display, "Creating dummy display");
gst_object_ref_sink (display);
}

View file

@ -50,9 +50,36 @@ GType gst_gl_display_get_type (void);
* @GST_GL_DISPLAY_TYPE_EGL: EGL display
* @GST_GL_DISPLAY_TYPE_VIV_FB: Vivante Framebuffer display
* @GST_GL_DISPLAY_TYPE_GBM: Mesa3D GBM display
* @GST_GL_DISPLAY_TYPE_EGL_DEVICE: EGLDevice display (Since: 1.18)
* @GST_GL_DISPLAY_TYPE_ANY: any display type
*/
/**
* GST_GL_DISPLAY_TYPE_EGL_DEVICE:
*
* EGLDevice display.
*
* Since: 1.18
*/
/**
* GST_GL_DISPLAY_TYPE_EAGL:
*
* EAGL display.
*
* Since: 1.20
*/
/**
* GST_GL_DISPLAY_TYPE_WINRT:
*
* WinRT display.
*
* Since: 1.20
*/
/**
* GST_GL_DISPLAY_TYPE_ANDROID:
*
* Android display.
*
* Since: 1.20
*/
typedef enum
{
GST_GL_DISPLAY_TYPE_NONE = 0,
@ -65,6 +92,9 @@ typedef enum
GST_GL_DISPLAY_TYPE_VIV_FB = (1 << 6),
GST_GL_DISPLAY_TYPE_GBM = (1 << 7),
GST_GL_DISPLAY_TYPE_EGL_DEVICE = (1 << 8),
GST_GL_DISPLAY_TYPE_EAGL = (1 << 9),
GST_GL_DISPLAY_TYPE_WINRT = (1 << 10),
GST_GL_DISPLAY_TYPE_ANDROID = (1 << 11),
GST_GL_DISPLAY_TYPE_ANY = G_MAXUINT32
} GstGLDisplayType;
@ -104,6 +134,8 @@ struct _GstGLDisplayClass
GST_GL_API
GstGLDisplay *gst_gl_display_new (void);
GST_GL_API
GstGLDisplay *gst_gl_display_new_with_type (GstGLDisplayType type);
#define gst_gl_display_lock(display) GST_OBJECT_LOCK (display)
#define gst_gl_display_unlock(display) GST_OBJECT_UNLOCK (display)