mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 16:26:39 +00:00
gl: add support for surfaceless display in GstGL
Use of the EGL_MESA_platform_surfaceless EGL extension to create an EGL display that is not depending on any kind of windowing system. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5511>
This commit is contained in:
parent
34694bbfcf
commit
e1ca575408
10 changed files with 107 additions and 14 deletions
|
@ -3016,7 +3016,7 @@ a #GstGLDisplay.
|
|||
There are a number of environment variables that influence the choice of
|
||||
platform and window system specific functionality.
|
||||
- GST_GL_WINDOW influences the window system to use. Common values are
|
||||
'x11', 'wayland', 'win32' or 'cocoa'.
|
||||
'x11', 'wayland', 'surfaceless', 'win32' or 'cocoa'.
|
||||
- GST_GL_PLATFORM influences the OpenGL platform to use. Common values are
|
||||
'egl', 'glx', 'wgl' or 'cgl'.
|
||||
- GST_GL_API influences the OpenGL API requested by the OpenGL platform.
|
||||
|
@ -3453,6 +3453,8 @@ display's object lock held.</doc>
|
|||
</member>
|
||||
<member name="android" value="2048" c:identifier="GST_GL_DISPLAY_TYPE_ANDROID" glib:nick="android">
|
||||
</member>
|
||||
<member name="egl_surfaceless" value="4096" c:identifier="GST_GL_DISPLAY_TYPE_EGL_SURFACELESS" glib:nick="egl-surfaceless">
|
||||
</member>
|
||||
<member name="any" value="4294967295" c:identifier="GST_GL_DISPLAY_TYPE_ANY" glib:nick="any">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstgldisplay.h">any display type</doc>
|
||||
</member>
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
* @see_also: #GstGLDisplay
|
||||
*
|
||||
* #GstGLDisplayEGL represents a connection to an EGL `EGLDisplay` handle created
|
||||
* internally (gst_gl_display_egl_new()) or wrapped by the application
|
||||
* (gst_gl_display_egl_new_with_egl_display())
|
||||
* internally (gst_gl_display_egl_new() or gst_gl_display_egl_new_surfaceless())
|
||||
* or wrapped by the application (gst_gl_display_egl_new_with_egl_display())
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
@ -122,8 +122,8 @@ gst_gl_display_egl_finalize (GObject * object)
|
|||
* @display: pointer to a display (or 0)
|
||||
*
|
||||
* Attempts to create a new `EGLDisplay` from @display. If @type is
|
||||
* %GST_GL_DISPLAY_TYPE_ANY, then @display must be 0. @type must not be
|
||||
* %GST_GL_DISPLAY_TYPE_NONE.
|
||||
* %GST_GL_DISPLAY_TYPE_ANY or %GST_GL_DISPLAY_TYPE_EGL_SURFACELESS, then
|
||||
* @display must be 0. @type must not be %GST_GL_DISPLAY_TYPE_NONE.
|
||||
*
|
||||
* Returns: (nullable): A `EGLDisplay` or `EGL_NO_DISPLAY`
|
||||
*
|
||||
|
@ -137,8 +137,11 @@ gst_gl_display_egl_get_from_native (GstGLDisplayType type, guintptr display)
|
|||
_gst_eglGetPlatformDisplay_type _gst_eglGetPlatformDisplay = NULL;
|
||||
|
||||
g_return_val_if_fail (type != GST_GL_DISPLAY_TYPE_NONE, EGL_NO_DISPLAY);
|
||||
g_return_val_if_fail ((type != GST_GL_DISPLAY_TYPE_ANY && display != 0)
|
||||
|| (type == GST_GL_DISPLAY_TYPE_ANY && display == 0), EGL_NO_DISPLAY);
|
||||
g_return_val_if_fail ((type != GST_GL_DISPLAY_TYPE_ANY &&
|
||||
type != GST_GL_DISPLAY_TYPE_EGL_SURFACELESS && display != 0)
|
||||
|| ((type == GST_GL_DISPLAY_TYPE_ANY ||
|
||||
type == GST_GL_DISPLAY_TYPE_EGL_SURFACELESS) && display == 0),
|
||||
EGL_NO_DISPLAY);
|
||||
|
||||
init_debug ();
|
||||
|
||||
|
@ -233,6 +236,11 @@ gst_gl_display_egl_get_from_native (GstGLDisplayType type, guintptr display)
|
|||
NULL);
|
||||
}
|
||||
/* android only has one winsys/display connection */
|
||||
if (ret == EGL_NO_DISPLAY && (type & GST_GL_DISPLAY_TYPE_EGL_SURFACELESS) &&
|
||||
gst_gl_check_extension ("EGL_MESA_platform_surfaceless", egl_exts)) {
|
||||
ret = _gst_eglGetPlatformDisplay (EGL_PLATFORM_SURFACELESS_MESA,
|
||||
(gpointer) display, NULL);
|
||||
}
|
||||
|
||||
if (ret != EGL_NO_DISPLAY)
|
||||
return ret;
|
||||
|
@ -272,6 +280,40 @@ gst_gl_display_egl_new (void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_gl_display_egl_new_surfaceless:
|
||||
*
|
||||
* Create a new surfaceless #GstGLDisplayEGL using the Mesa3D
|
||||
* EGL_PLATFORM_SURFACELESS_MESA extension.
|
||||
*
|
||||
* Returns: (transfer full) (nullable): a new #GstGLDisplayEGL or %NULL
|
||||
*
|
||||
* Since: 1.24
|
||||
*/
|
||||
GstGLDisplayEGL *
|
||||
gst_gl_display_egl_new_surfaceless (void)
|
||||
{
|
||||
GstGLDisplayEGL *ret;
|
||||
gpointer display;
|
||||
|
||||
init_debug ();
|
||||
|
||||
display =
|
||||
gst_gl_display_egl_get_from_native (GST_GL_DISPLAY_TYPE_EGL_SURFACELESS,
|
||||
0);
|
||||
|
||||
if (!display) {
|
||||
GST_INFO ("Failed to create a surfaceless EGL display");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = g_object_new (GST_TYPE_GL_DISPLAY_EGL, NULL);
|
||||
gst_object_ref_sink (ret);
|
||||
ret->display = display;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_gl_display_egl_new_with_display:
|
||||
* @display: an existing and connected EGLDisplay
|
||||
|
|
|
@ -66,6 +66,9 @@ struct _GstGLDisplayEGLClass
|
|||
GST_GL_API
|
||||
GstGLDisplayEGL *gst_gl_display_egl_new (void);
|
||||
|
||||
GST_GL_API
|
||||
GstGLDisplayEGL *gst_gl_display_egl_new_surfaceless (void);
|
||||
|
||||
GST_GL_API
|
||||
GstGLDisplayEGL *gst_gl_display_egl_new_with_egl_display (gpointer display);
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
* There are a number of environment variables that influence the choice of
|
||||
* platform and window system specific functionality.
|
||||
* - GST_GL_WINDOW influences the window system to use. Common values are
|
||||
* 'x11', 'wayland', 'win32' or 'cocoa'.
|
||||
* 'x11', 'wayland', 'surfaceless', 'win32' or 'cocoa'.
|
||||
* - GST_GL_PLATFORM influences the OpenGL platform to use. Common values are
|
||||
* 'egl', 'glx', 'wgl' or 'cgl'.
|
||||
* - GST_GL_API influences the OpenGL API requested by the OpenGL platform.
|
||||
|
@ -310,6 +310,8 @@ gst_gl_display_type_from_environment (void)
|
|||
return GST_GL_DISPLAY_TYPE_EGL;
|
||||
} else if (g_strstr_len (env, 5, "winrt")) {
|
||||
return GST_GL_DISPLAY_TYPE_EGL;
|
||||
} else if (g_strstr_len (env, 11, "surfaceless")) {
|
||||
return GST_GL_DISPLAY_TYPE_EGL_SURFACELESS;
|
||||
} else {
|
||||
return GST_GL_DISPLAY_TYPE_NONE;
|
||||
}
|
||||
|
@ -393,9 +395,14 @@ gst_gl_display_new_with_type (GstGLDisplayType type)
|
|||
if (!display && (type & GST_GL_DISPLAY_TYPE_EGL)) {
|
||||
display = GST_GL_DISPLAY (gst_gl_display_egl_new ());
|
||||
}
|
||||
|
||||
if (!display && (type & GST_GL_DISPLAY_TYPE_EGL_SURFACELESS)) {
|
||||
display = GST_GL_DISPLAY (gst_gl_display_egl_new_surfaceless ());
|
||||
}
|
||||
#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_EGL_SURFACELESS;
|
||||
custom_new_types |= GST_GL_DISPLAY_TYPE_DISPMANX;
|
||||
custom_new_types |= GST_GL_DISPLAY_TYPE_WINRT;
|
||||
custom_new_types |= GST_GL_DISPLAY_TYPE_ANDROID;
|
||||
|
|
|
@ -80,6 +80,14 @@ GType gst_gl_display_get_type (void);
|
|||
*
|
||||
* Since: 1.20
|
||||
*/
|
||||
/**
|
||||
* GST_GL_DISPLAY_TYPE_EGL_SURFACELESS:
|
||||
*
|
||||
* Mesa3D surfaceless display using the EGL_PLATFORM_SURFACELESS_MESA
|
||||
* extension.
|
||||
*
|
||||
* Since: 1.24
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GST_GL_DISPLAY_TYPE_NONE = 0,
|
||||
|
@ -95,6 +103,7 @@ typedef enum
|
|||
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_EGL_SURFACELESS = (1 << 12),
|
||||
|
||||
GST_GL_DISPLAY_TYPE_ANY = G_MAXUINT32
|
||||
} GstGLDisplayType;
|
||||
|
|
|
@ -334,6 +334,9 @@ gst_gl_window_new (GstGLDisplay * display)
|
|||
if (!window && (!user_choice || g_strstr_len (user_choice, 5, "winrt")))
|
||||
window = GST_GL_WINDOW (gst_gl_window_winrt_egl_new (display));
|
||||
#endif
|
||||
if (!window && (!user_choice
|
||||
|| g_strstr_len (user_choice, 11, "surfaceless")))
|
||||
window = GST_GL_WINDOW (gst_gl_dummy_window_new ());
|
||||
|
||||
if (!window) {
|
||||
/* subclass returned a NULL window */
|
||||
|
|
|
@ -253,6 +253,7 @@ if gl_winsys.contains('auto')
|
|||
need_win_winrt = 'auto'
|
||||
need_win_cocoa = 'auto'
|
||||
need_win_egl = 'auto'
|
||||
need_win_surfaceless = 'auto'
|
||||
need_win_eagl = 'auto'
|
||||
need_win_dispmanx = 'auto'
|
||||
need_win_viv_fb = 'auto'
|
||||
|
@ -265,6 +266,7 @@ else
|
|||
need_win_winrt = 'no'
|
||||
need_win_cocoa = 'no'
|
||||
need_win_egl = 'no'
|
||||
need_win_surfaceless = 'no'
|
||||
need_win_eagl = 'no'
|
||||
need_win_dispmanx = 'no'
|
||||
need_win_viv_fb = 'no'
|
||||
|
@ -283,6 +285,8 @@ else
|
|||
need_win_cocoa = 'yes'
|
||||
elif winsys == 'egl'
|
||||
need_win_egl = 'yes'
|
||||
elif winsys == 'surfaceless'
|
||||
need_win_surfaceless = 'yes'
|
||||
elif winsys == 'eagl'
|
||||
need_win_eagl = 'yes'
|
||||
elif winsys == 'dispmanx'
|
||||
|
@ -578,16 +582,39 @@ if need_platform_egl != 'no'
|
|||
endif
|
||||
|
||||
# winsys_egl checks
|
||||
if need_win_egl == 'yes'
|
||||
if need_win_egl != 'no'
|
||||
if need_platform_egl == 'no'
|
||||
error('Impossible situation requested: Cannot use Winsys egl without EGL support')
|
||||
if need_win_egl == 'yes'
|
||||
error ('Impossible situation requested: Cannot use Winsys egl without EGL support')
|
||||
endif
|
||||
elif not egl_dep.found()
|
||||
error ('Could not find EGL libraries for Winsys egl')
|
||||
if need_win_egl == 'yes'
|
||||
error ('Could not find EGL libraries for Winsys egl')
|
||||
else
|
||||
message ('Could not find EGL libraries for Winsys egl')
|
||||
endif
|
||||
else
|
||||
enabled_gl_winsys += 'egl'
|
||||
endif
|
||||
endif
|
||||
|
||||
# winsys_surfaceless checks
|
||||
if need_win_surfaceless != 'no'
|
||||
if need_platform_egl == 'no'
|
||||
if need_win_surfaceless == 'yes'
|
||||
error ('Impossible situation requested: Cannot use Winsys surfaceless without EGL support')
|
||||
endif
|
||||
elif not egl_dep.found()
|
||||
if need_win_surfaceless == 'yes'
|
||||
error ('Could not find EGL libraries for Winsys surfaceless')
|
||||
else
|
||||
message ('Could not find EGL libraries for Winsys surfaceless')
|
||||
endif
|
||||
else
|
||||
enabled_gl_winsys += 'surfaceless'
|
||||
endif
|
||||
endif
|
||||
|
||||
# wayland checks
|
||||
wayland_client_dep = unneeded_dep
|
||||
wayland_cursor_dep = unneeded_dep
|
||||
|
|
|
@ -12,7 +12,7 @@ option('gl_platform', type : 'array',
|
|||
choices : ['glx', 'egl', 'cgl', 'wgl', 'eagl', 'auto'], value : ['auto'],
|
||||
description : 'A comma separated list of opengl platforms to enable building against')
|
||||
option('gl_winsys', type : 'array',
|
||||
choices : ['x11', 'wayland', 'win32', 'winrt', 'cocoa', 'dispmanx', 'egl', 'viv-fb', 'gbm', 'android', 'auto'], value : ['auto'],
|
||||
choices : ['x11', 'wayland', 'win32', 'winrt', 'cocoa', 'dispmanx', 'egl', 'surfaceless', 'viv-fb', 'gbm', 'android', 'auto'], value : ['auto'],
|
||||
description : 'A comma separated list of opengl windows systems to enable building against. Supported values are x11, wayland, win32, winrt, cocoa, dispmanx, egl, viv-fb, gbm, and android')
|
||||
option('egl_module_name', type : 'string', value : '',
|
||||
description : 'The file to pass to g_module_open to open the libEGL library (default: libEGL)')
|
||||
|
|
|
@ -315,7 +315,7 @@ the encoding does not look like UTF-8.
|
|||
**`GST_GL_WINDOW`.**
|
||||
|
||||
Influences the window system to use by the GStreamer OpenGL library.
|
||||
Common values are 'x11', 'wayland', 'win32' or 'cocoa'.
|
||||
Common values are 'x11', 'wayland', 'surfaceless', 'win32' or 'cocoa'.
|
||||
|
||||
**`GST_GL_PLATFORM`.**
|
||||
|
||||
|
|
|
@ -325,7 +325,7 @@ the encoding does not look like UTF-8.
|
|||
**GST_GL_WINDOW.**
|
||||
|
||||
Influences the window system to use by the GStreamer OpenGL library.
|
||||
Common values are 'x11', 'wayland', 'win32' or 'cocoa'.
|
||||
Common values are 'x11', 'wayland', 'surfaceless', 'win32' or 'cocoa'.
|
||||
|
||||
**GST_GL_PLATFORM.**
|
||||
|
||||
|
|
Loading…
Reference in a new issue