[vlc-devel] [PATCH 2/2] egl_pbuffer: add GBM platform support
Rémi Denis-Courmont
remi at remlab.net
Tue Mar 2 17:34:55 UTC 2021
Le tiistaina 2. maaliskuuta 2021, 15.51.39 EET Romain Vimont a écrit :
> From: Alexandre Janniaux <ajanni at videolabs.io>
>
> GBM platform allows to provide an EGL context even without display
> server.
>
> Co-authored-by: Romain Vimont <rom1v at videolabs.io>
> ---
> configure.ac | 18 ++++
> modules/video_filter/egl_pbuffer.c | 114 ++++++++++++++++++++++--
> modules/video_output/opengl/Makefile.am | 4 +
> 3 files changed, 127 insertions(+), 9 deletions(-)
>
> diff --git a/configure.ac b/configure.ac
> index a82c956c70..cd546da9ca 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -4464,6 +4464,24 @@ AS_IF([test "${enable_osx_notifications}" != "no"], [
> VLC_ADD_PLUGIN([osx_notifications])
> ])
>
> +dnl
> +dnl Check for GBM
> +dnl
> +AC_ARG_ENABLE([gbm],
> + AS_HELP_STRING([--enable-gbm],
> + [Use GBM for egl_pbuffer (default enabled)]))
> +have_gbm="no"
> +AS_IF([test "${enable_gbm}" != "no"], [
> + PKG_CHECK_MODULES([GBM], [gbm], [have_gbm="yes"], [
> + AS_IF([test -n "${enable_gbm}"], [
> + AC_MSG_ERROR([${GBM_PKG_ERRORS}.])
> + ], [
> + AC_MSG_WARN([${GBM_PKG_ERRORS}.])
> + ])
> + ])
> +])
> +AM_CONDITIONAL([HAVE_GBM], [test "${have_gbm}" = "yes"])
> +
> dnl
> dnl Libnotify notification plugin
> dnl
> diff --git a/modules/video_filter/egl_pbuffer.c
> b/modules/video_filter/egl_pbuffer.c index 78cd48b3fd..9554036c1b 100644
> --- a/modules/video_filter/egl_pbuffer.c
> +++ b/modules/video_filter/egl_pbuffer.c
> @@ -29,6 +29,8 @@
> #include <vlc_opengl.h>
> #include <vlc_vout_display.h>
> #include <vlc_atomic.h>
> +#include <vlc_fs.h>
> +#include <fcntl.h>
> #include "../video_output/opengl/vout_helper.h"
> #include "../video_output/opengl/filters.h"
> #include "../video_output/opengl/gl_api.h"
> @@ -37,6 +39,10 @@
> #include <EGL/egl.h>
> #include <EGL/eglext.h>
>
> +#ifdef HAVE_GBM
> +#include <gbm.h>
> +#endif
> +
> #define BUFFER_COUNT 4
>
> struct pbo_picture_context
> @@ -72,6 +78,11 @@ struct vlc_gl_pbuffer
> PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR;
>
> bool current;
> +
> +#ifdef HAVE_GBM
> + struct gbm_device *gbm_device;
> + int gbm_device_fd;
> +#endif
> };
>
> static int MakeCurrent (vlc_gl_t *gl)
> @@ -148,6 +159,43 @@ static bool GetPlatform(const char *extensions, EGLenum
> *out) return false;
> }
>
> +#ifdef HAVE_GBM
> +static bool InitGBMDisplay(vlc_gl_t *gl) {
> + struct vlc_gl_pbuffer *sys = gl->sys;
> +
> + const char *extensions = eglQueryString(EGL_NO_DISPLAY,
> EGL_EXTENSIONS); + if (!extensions)
> + return false;
> +
> + if (!vlc_gl_StrHasToken(extensions, "EGL_KHR_platform_gbm"))
> + return false;
> +
> + sys->gbm_device_fd = vlc_open("/dev/dri/card0", O_RDWR);
> + if (sys->gbm_device_fd < 0)
> + return false;
> +
> + sys->gbm_device = gbm_create_device(sys->gbm_device_fd);
> + if (sys->gbm_device == NULL)
> + {
> + vlc_close(sys->gbm_device_fd);
> + return false;
> + }
> +
> + sys->display = eglGetPlatformDisplay(EGL_PLATFORM_GBM_KHR,
> + sys->gbm_device, NULL);
> + if (sys->display == EGL_NO_DISPLAY)
> + {
> + gbm_device_destroy(sys->gbm_device);
> + vlc_close(sys->gbm_device_fd);
> + sys->gbm_device = NULL;
> + return false;
> + }
> +
> + msg_Info(gl, "EGL using GBM platform on device fd %d",
> sys->gbm_device_fd); + return true;
> +}
> +#endif
> +
> static bool InitDefaultEGLDisplay(vlc_gl_t *gl)
> {
> struct vlc_gl_pbuffer *sys = gl->sys;
> @@ -181,8 +229,17 @@ static int InitEGL(vlc_gl_t *gl, unsigned width,
> unsigned height) {
> struct vlc_gl_pbuffer *sys = gl->sys;
>
> - if (!InitDefaultEGLDisplay(gl))
> - return VLC_EGENERIC;
> + bool has_display = false;
> +
> +#ifdef HAVE_GBM
> + has_display = InitGBMDisplay(gl);
> +#endif
> +
> + if (!has_display)
> + {
> + if (!InitDefaultEGLDisplay(gl))
> + return VLC_EGENERIC;
> + }
>
> /* Initialize EGL display */
> EGLint major, minor;
> @@ -198,7 +255,11 @@ static int InitEGL(vlc_gl_t *gl, unsigned width,
> unsigned height) #endif
> );
>
> - const EGLint conf_attr[] = {
> + const char *extensions = eglQueryString(sys->display, EGL_EXTENSIONS);
> + bool need_surface =
> + !vlc_gl_StrHasToken(extensions, "EGL_KHR_surfaceless_context");
> +
> + const EGLint conf_attr_surface[] = {
> EGL_RED_SIZE, 8,
> EGL_GREEN_SIZE, 8,
> EGL_BLUE_SIZE, 8,
> @@ -210,6 +271,22 @@ static int InitEGL(vlc_gl_t *gl, unsigned width,
> unsigned height) EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
> EGL_NONE,
> };
> +
> + const EGLint conf_attr_surfaceless[] = {
> +#ifdef USE_OPENGL_ES2
> + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
> +#else
> + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
> +#endif
> + EGL_NONE,
> + };
> +
> + const EGLint *conf_attr;
> + if (need_surface)
> + conf_attr = conf_attr_surface;
> + else
> + conf_attr = conf_attr_surfaceless;
> +
> EGLConfig cfgv[1];
> EGLint cfgc;
>
> @@ -227,14 +304,20 @@ static int InitEGL(vlc_gl_t *gl, unsigned width,
> unsigned height) goto error;
> }
>
> - /* Create a drawing surface */
> - sys->surface = eglCreatePbufferSurface(sys->display, cfgv[0],
> surface_attr); - if (sys->surface == EGL_NO_SURFACE)
> + if (need_surface)
> {
> - msg_Err (gl, "cannot create EGL window surface");
> - assert(false);
> - goto error;
> + /* Create a drawing surface */
> + sys->surface = eglCreatePbufferSurface(sys->display, cfgv[0],
> + surface_attr);
> + if (sys->surface == EGL_NO_SURFACE)
> + {
> + msg_Err (gl, "cannot create EGL window surface");
> + assert(false);
> + goto error;
> + }
> }
> + else
> + sys->surface = EGL_NO_SURFACE;
>
> #ifdef USE_OPENGL_ES2
> if (eglBindAPI (EGL_OPENGL_ES_API) != EGL_TRUE)
> @@ -401,6 +484,14 @@ static void Close( vlc_gl_t *gl )
> vt->DeleteFramebuffers(BUFFER_COUNT, sys->framebuffers);
> vt->DeleteTextures(BUFFER_COUNT, sys->textures);
> vlc_gl_ReleaseCurrent(sys->gl);
> +
> +#ifdef HAVE_GBM
> + if (sys->gbm_device)
> + gbm_device_destroy(sys->gbm_device);
> +
> + if (sys->gbm_device_fd >= 0)
> + vlc_close(sys->gbm_device_fd);
> +#endif
> }
>
> static int Open(vlc_gl_t *gl, unsigned width, unsigned height)
> @@ -426,6 +517,11 @@ static int Open(vlc_gl_t *gl, unsigned width, unsigned
> height) vlc_mutex_init(&sys->lock);
> vlc_cond_init(&sys->cond);
>
> +#ifdef HAVE_GBM
> + sys->gbm_device = NULL;
> + sys->gbm_device_fd = -1;
> +#endif
> +
> gl->sys = sys;
>
> if (InitEGL(gl, width, height) != VLC_SUCCESS)
> diff --git a/modules/video_output/opengl/Makefile.am
> b/modules/video_output/opengl/Makefile.am index d3170d9ac7..47a0d32ec3
> 100644
> --- a/modules/video_output/opengl/Makefile.am
> +++ b/modules/video_output/opengl/Makefile.am
> @@ -92,6 +92,10 @@ endif # HAVE_GL
> libegl_pbuffer_filter_plugin_la_SOURCES = video_filter/egl_pbuffer.c
> libegl_pbuffer_filter_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) $(EGL_FLAGS)
> libegl_pbuffer_filter_plugin_la_LIBADD = $(LIBM) $(EGL_LIBS)
> +if HAVE_GBM
> +libegl_pbuffer_filter_plugin_la_CPPFLAGS += $(GBM_CFLAGS) -DHAVE_GBM
> +libegl_pbuffer_filter_plugin_la_LIBADD += $(GBM_LIBS)
> +endif
No way. We are not entangling X11, Wayland and GBM in one plugin. Not again.
>
> if HAVE_LINUX
> if HAVE_GL
--
レミ・デニ-クールモン
http://www.remlab.net/
More information about the vlc-devel
mailing list