vlc | branch: master | Alexandre Janniaux <[email protected]> | Mon Mar 22 16:06:25 2021 +0100| [db48d216824315ddf5240bd73175cbe7fbfe220d] | committer: Alexandre Janniaux
egl_display: add GBM platform support GBM platform allows to provide an EGL context even without display server. Co-authored-by: Romain Vimont <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=db48d216824315ddf5240bd73175cbe7fbfe220d --- configure.ac | 18 ++++ modules/video_output/opengl/Makefile.am | 9 ++ modules/video_output/opengl/egl_display_gbm.c | 132 ++++++++++++++++++++++++++ 3 files changed, 159 insertions(+) diff --git a/configure.ac b/configure.ac index ea0bb759f3..b774a34ddc 100644 --- a/configure.ac +++ b/configure.ac @@ -4467,6 +4467,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_output/opengl/Makefile.am b/modules/video_output/opengl/Makefile.am index c7cbdedfb6..d496093d75 100644 --- a/modules/video_output/opengl/Makefile.am +++ b/modules/video_output/opengl/Makefile.am @@ -96,6 +96,15 @@ if HAVE_EGL vout_LTLIBRARIES += libegl_display_generic_plugin.la endif +libegl_display_gbm_plugin_la_SOURCES = video_output/opengl/egl_display_gbm.c +libegl_display_gbm_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) $(EGL_FLAGS) $(GBM_CFLAGS) +libegl_display_gbm_plugin_la_LIBADD = $(EGL_LIBS) $(GBM_LIBS) +if HAVE_EGL +if HAVE_GBM +vout_LTLIBRARIES += libegl_display_gbm_plugin.la +endif +endif + libegl_pbuffer_filter_plugin_la_SOURCES = video_filter/egl_pbuffer.c \ video_output/opengl/egl_display.c libegl_pbuffer_filter_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) $(EGL_FLAGS) diff --git a/modules/video_output/opengl/egl_display_gbm.c b/modules/video_output/opengl/egl_display_gbm.c new file mode 100644 index 0000000000..ab2635cd12 --- /dev/null +++ b/modules/video_output/opengl/egl_display_gbm.c @@ -0,0 +1,132 @@ +/***************************************************************************** + * egl_display_gbm.c + ***************************************************************************** + * Copyright (C) 2021 Videolabs + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <vlc_common.h> +#include <vlc_plugin.h> +#include <vlc_opengl.h> +#include <vlc_fs.h> +#include <fcntl.h> +#include <assert.h> + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <gbm.h> + +#include "egl_display.h" + +struct sys +{ + struct gbm_device *device; + int fd; +}; + +static void Close(struct vlc_egl_display *display) +{ + struct sys *sys = display->sys; + + assert(sys->device); + assert(sys->fd >= 0); + + gbm_device_destroy(sys->device); + vlc_close(sys->fd); + + free(sys); +} + +static int +OpenDeviceFd(const char **out_path) +{ + static const char *default_drm_device_paths[] = { + "/dev/dri/renderD128", + "/dev/dri/card0", + "/dev/dri/renderD129", + "/dev/dri/card1", + }; + + for (size_t i = 0; i < ARRAY_SIZE(default_drm_device_paths); ++i) + { + const char *path = default_drm_device_paths[i]; + int fd = vlc_open(path, O_RDWR); + if (fd >= 0) + { + *out_path = path; + return fd; + } + } + + return -1; +} + +static vlc_egl_display_open_fn Open; +static int +Open(struct vlc_egl_display *display) +{ + struct sys *sys = display->sys = malloc(sizeof(*sys)); + if (!sys) + return VLC_EGENERIC; + + const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); + if (!extensions) + return VLC_EGENERIC; + + if (!vlc_gl_StrHasToken(extensions, "EGL_KHR_platform_gbm")) + return VLC_EGENERIC; + + const char *device_path; + sys->fd = OpenDeviceFd(&device_path); + if (sys->fd < 0) + return VLC_EGENERIC; + + sys->device = gbm_create_device(sys->fd); + if (!sys->device) + { + vlc_close(sys->fd); + return VLC_EGENERIC; + } + + display->display = eglGetPlatformDisplay(EGL_PLATFORM_GBM_KHR, sys->device, + NULL); + if (display->display == EGL_NO_DISPLAY) + { + gbm_device_destroy(sys->device); + vlc_close(sys->fd); + return VLC_EGENERIC; + } + + static const struct vlc_egl_display_ops ops = { + .close = Close, + }; + display->ops = &ops; + + msg_Info(display, "EGL using GBM platform on device %s (fd=%d)", + device_path, sys->fd); + return VLC_SUCCESS; +} + +vlc_module_begin() + set_description("EGL GBM display") + set_capability("egl display", 2) + set_callback(Open) + add_shortcut("egl_display_gbm") +vlc_module_end() _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
