gl/egl/display: Add support EGLDevice display type

Simple addition for supporting EXT_platform_device typed display.
It's a kind of special display type (part of EGL specification)
which has no window at all.
To use EGLDevice explicitly, set environment "GST_GL_WINDOW=egl-device"

See also https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_platform_device.txt
This commit is contained in:
Seungha Yang 2019-04-04 17:41:13 +09:00 committed by Matthew Waters
parent 7a378ba3ab
commit 5f70adf667
10 changed files with 286 additions and 4 deletions

View file

@ -98,6 +98,7 @@ if build_gstgl
join_paths('../gst-libs/gst', 'gl', 'egl', 'gstegl.[ch]'),
join_paths('../gst-libs/gst', 'gl', 'egl', 'gsteglimage.[ch]'),
join_paths('../gst-libs/gst', 'gl', 'egl', 'gstgldisplay_egl.[ch]'),
join_paths('../gst-libs/gst', 'gl', 'egl', 'gstgldisplay_egl_device.[ch]'),
join_paths('../gst-libs/gst', 'gl', 'egl', 'gstglmemoryegl.[ch]'),
join_paths('../gst-libs/gst', 'gl', 'x11', 'gstgldisplay_x11.[ch]'),
join_paths('../gst-libs/gst', 'gl', 'wayland', 'gstgldisplay_wayland.[ch]'),

View file

@ -149,7 +149,9 @@ if USE_EGL
SUBDIRS += egl
libgstgl_@GST_API_VERSION@_la_LIBADD += egl/libgstgl-egl.la
gstgl_gir_headers += egl/gstgldisplay_egl.h
gstgl_gir_headers += egl/gstgldisplay_egl_device.h
gstgl_gir_sources += egl/gstgldisplay_egl.c
gstgl_gir_sources += egl/gstgldisplay_egl_device.c
endif
configexecincludedir = $(libdir)/gstreamer-@GST_API_VERSION@/include/gst/gl

View file

@ -7,7 +7,8 @@ libgstgl_egl_la_SOURCES = \
gstglcontext_egl.c \
gstglmemoryegl.c \
gsteglimage.c \
gstegl.c
gstegl.c \
gstgldisplay_egl_device.c
noinst_HEADERS = \
gstglcontext_egl.h
@ -17,7 +18,8 @@ libgstgl_eglinclude_HEADERS = \
gstgldisplay_egl.h \
gstglmemoryegl.h \
gsteglimage.h \
gstegl.h
gstegl.h \
gstgldisplay_egl_device.h
libgstgl_egl_la_CFLAGS = \
-I$(top_srcdir)/gst-libs \

View file

@ -409,6 +409,16 @@ gst_gl_context_egl_choose_config (GstGLContextEGL * egl, GstGLAPI gl_api,
EGLint config_attrib[20];
EGLint egl_api = 0;
EGLBoolean ret = EGL_FALSE;
EGLint surface_type = EGL_WINDOW_BIT;
GstGLWindow *window;
window = gst_gl_context_get_window (GST_GL_CONTEXT (egl));
if (!window || !gst_gl_window_has_output_surface (window)) {
GST_INFO_OBJECT (egl,
"gl window has no output surface, use pixel buffer surfaces");
surface_type = EGL_PBUFFER_BIT;
}
create_context =
gst_gl_check_extension ("EGL_KHR_create_context", egl->egl_exts);
@ -432,7 +442,7 @@ gst_gl_context_egl_choose_config (GstGLContextEGL * egl, GstGLAPI gl_api,
egl_api = EGL_OPENGL_BIT;
config_attrib[i++] = EGL_SURFACE_TYPE;
config_attrib[i++] = EGL_WINDOW_BIT;
config_attrib[i++] = surface_type;
config_attrib[i++] = EGL_RENDERABLE_TYPE;
config_attrib[i++] = egl_api;
#if defined(USE_EGL_RPI) && GST_GL_HAVE_WINDOW_WAYLAND

View file

@ -56,6 +56,9 @@ GST_DEBUG_CATEGORY_STATIC (gst_gl_display_debug);
#ifndef EGL_PLATFORM_ANDROID
#define EGL_PLATFORM_ANDROID 0x3141
#endif
#ifndef EGL_PLATFORM_DEVICE_EXT
#define EGL_PLATFORM_DEVICE_EXT 0x313F
#endif
typedef EGLDisplay (*_gst_eglGetPlatformDisplay_type) (EGLenum platform,
void *native_display, const EGLint * attrib_list);
@ -125,6 +128,8 @@ gst_gl_display_egl_get_from_native (GstGLDisplayType type, guintptr 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);
GST_DEBUG_CATEGORY_GET (gst_gl_display_debug, "gldisplay");
/* given an EGLDisplay already */
if (type == GST_GL_DISPLAY_TYPE_EGL)
return (gpointer) display;
@ -175,6 +180,14 @@ gst_gl_display_egl_get_from_native (GstGLDisplayType type, guintptr display)
NULL);
}
#endif
if (ret == EGL_NO_DISPLAY && (type & GST_GL_DISPLAY_TYPE_EGL_DEVICE) &&
(gst_gl_check_extension ("EGL_EXT_device_base", egl_exts) &&
gst_gl_check_extension ("EGL_EXT_platform_device", egl_exts))) {
ret =
_gst_eglGetPlatformDisplay (EGL_PLATFORM_DEVICE_EXT, (gpointer) display,
NULL);
}
/* android only has one winsys/display connection */
if (ret != EGL_NO_DISPLAY)

View file

@ -0,0 +1,162 @@
/*
* GStreamer
* Copyright (C) 2014 Matthew Waters <ystreet00@gmail.com>
* Copyright (C) 2019 Seungha Yang <seungha.yang@navercorp.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/**
* SECTION:gstgldisplay_egl_device
* @short_description: EGL EGLDeviceEXT object
* @title: GstGLDisplayEGLDevice
* @see_also: #GstGLDisplay, #GstGLDisplayEGL
*
* #GstGLDisplayEGLDevice represents a `EGLDeviceEXT` handle created internally
* (gst_gl_display_egl_device_new()) or wrapped by the application
* (gst_gl_display_egl_device_new_with_egl_device())
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstgldisplay_egl.h"
#include "gstgldisplay_egl_device.h"
#include <gst/gl/gstglfeature.h>
#include "gstegl.h"
#include "gstglmemoryegl.h"
GST_DEBUG_CATEGORY_STATIC (gst_gl_display_debug);
#define GST_CAT_DEFAULT gst_gl_display_debug
typedef EGLBoolean (*eglQueryDevicesEXT_type) (EGLint max_devices,
EGLDeviceEXT * devices, EGLint * num_devices);
G_DEFINE_TYPE (GstGLDisplayEGLDevice, gst_gl_display_egl_device,
GST_TYPE_GL_DISPLAY);
static guintptr gst_gl_display_egl_device_get_handle (GstGLDisplay * display);
static void
gst_gl_display_egl_device_class_init (GstGLDisplayEGLDeviceClass * klass)
{
GstGLDisplayClass *display_class = GST_GL_DISPLAY_CLASS (klass);
display_class->get_handle =
GST_DEBUG_FUNCPTR (gst_gl_display_egl_device_get_handle);
}
static void
gst_gl_display_egl_device_init (GstGLDisplayEGLDevice * self)
{
GstGLDisplay *display = GST_GL_DISPLAY (self);
display->type = GST_GL_DISPLAY_TYPE_EGL_DEVICE;
gst_gl_memory_egl_init_once ();
}
static guintptr
gst_gl_display_egl_device_get_handle (GstGLDisplay * display)
{
GstGLDisplayEGLDevice *self = GST_GL_DISPLAY_EGL_DEVICE (display);
return (guintptr) self->device;
}
/**
* gst_gl_display_egl_device_new:
* @device_index: the index of device to use
*
* Create a new #GstGLDisplayEGLDevice with an EGLDevice supported device
*
* Returns: (transfer full): a new #GstGLDisplayEGLDevice or %NULL
*
* Since: 1.18
*/
GstGLDisplayEGLDevice *
gst_gl_display_egl_device_new (guint device_index)
{
GstGLDisplayEGLDevice *ret;
eglQueryDevicesEXT_type query_device_func;
EGLint num_devices = 0;
EGLDeviceEXT *device_list;
GST_DEBUG_CATEGORY_GET (gst_gl_display_debug, "gldisplay");
query_device_func =
(eglQueryDevicesEXT_type) eglGetProcAddress ("eglQueryDevicesEXT");
if (!query_device_func) {
GST_ERROR ("eglQueryDevicesEXT is unavailable");
return NULL;
}
if (query_device_func (0, NULL, &num_devices) == EGL_FALSE) {
GST_ERROR ("eglQueryDevicesEXT fail");
return NULL;
} else if (num_devices < 1) {
GST_ERROR ("no EGLDevice supported device");
return NULL;
}
if (num_devices <= device_index) {
GST_ERROR ("requested index %d exceeds the number of devices %d",
device_index, num_devices);
return NULL;
}
device_list = g_alloca (sizeof (EGLDeviceEXT) * num_devices);
query_device_func (num_devices, device_list, &num_devices);
ret = g_object_new (GST_TYPE_GL_DISPLAY_EGL_DEVICE, NULL);
gst_object_ref_sink (ret);
ret->device = device_list[device_index];
return ret;
}
/**
* gst_gl_display_egl_device_new_with_egl_device:
* @device: an existing EGLDeviceEXT
*
* Creates a new #GstGLDisplayEGLDevice with EGLDeviceEXT .
* The @device must be created using EGLDevice enumeration.
*
* Returns: (transfer full): a new #GstGLDisplayEGLDevice
*
* Since: 1.18
*/
GstGLDisplayEGLDevice *
gst_gl_display_egl_device_new_with_egl_device (gpointer device)
{
GstGLDisplayEGLDevice *ret;
g_return_val_if_fail (device != NULL, NULL);
GST_DEBUG_CATEGORY_GET (gst_gl_display_debug, "gldisplay");
ret = g_object_new (GST_TYPE_GL_DISPLAY_EGL_DEVICE, NULL);
gst_object_ref_sink (ret);
ret->device = device;
return ret;
}

View file

@ -0,0 +1,82 @@
/*
* GStreamer
* Copyright (C) 2014 Matthew Waters <ystreet00@gmail.com>
* Copyright (C) 2019 Seungha Yang <seungha.yang@navercorp.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef __GST_GL_DISPLAY_EGL_DEVICE_H__
#define __GST_GL_DISPLAY_EGL_DEVICE_H__
#include <gst/gl/gstgldisplay.h>
G_BEGIN_DECLS
GST_GL_API
GType gst_gl_display_egl_device_get_type (void);
#define GST_TYPE_GL_DISPLAY_EGL_DEVICE (gst_gl_display_egl_device_get_type())
#define GST_GL_DISPLAY_EGL_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_DISPLAY_EGL_DEVICE,GstGLDisplayEGLDevice))
#define GST_GL_DISPLAY_EGL_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_GL_DISPLAY_EGL_DEVICE,GstGLDisplayEGLDeviceClass))
#define GST_IS_GL_DISPLAY_EGL_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_DISPLAY_EGL_DEVICE))
#define GST_IS_GL_DISPLAY_EGL_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_GL_DISPLAY_EGL_DEVICE))
#define GST_GL_DISPLAY_EGL_DEVICE_CAST(obj) ((GstGLDisplayEGLDevice*)(obj))
typedef struct _GstGLDisplayEGLDevice GstGLDisplayEGLDevice;
typedef struct _GstGLDisplayEGLDeviceClass GstGLDisplayEGLDeviceClass;
/**
* GstGLDisplayEGLDevice:
*
* the contents of a #GstGLDisplayEGLDevice are private and should only be accessed
* through the provided API
*
* Since: 1.18
*/
struct _GstGLDisplayEGLDevice
{
GstGLDisplay parent;
gpointer device;
gpointer _padding[GST_PADDING];
};
/**
* GstGLDisplayEGLDeviceClass:
*
* Opaque #GstGLDisplayEGLDeviceClass struct
*
* Since: 1.18
*/
struct _GstGLDisplayEGLDeviceClass
{
GstGLDisplayClass object_class;
gpointer _padding[GST_PADDING];
};
GST_GL_API
GstGLDisplayEGLDevice *gst_gl_display_egl_device_new (guint device_index);
GST_GL_API
GstGLDisplayEGLDevice *gst_gl_display_egl_device_new_with_egl_device (gpointer device);
G_END_DECLS
#endif /* __GST_GL_DISPLAY_EGL_DEVICE_H__ */

View file

@ -67,6 +67,7 @@
#endif
#if GST_GL_HAVE_PLATFORM_EGL
#include <gst/gl/egl/gstgldisplay_egl.h>
#include <gst/gl/egl/gstgldisplay_egl_device.h>
#include <gst/gl/egl/gsteglimage.h>
#include <gst/gl/egl/gstglmemoryegl.h>
#endif
@ -321,9 +322,14 @@ gst_gl_display_new (void)
}
#endif
#if GST_GL_HAVE_PLATFORM_EGL
if (!display && (user_choice && g_strstr_len (user_choice, 10, "egl-device"))) {
display = GST_GL_DISPLAY (gst_gl_display_egl_device_new (0));
}
if (!display && (!platform_choice
|| g_strstr_len (platform_choice, 3, "egl")))
|| g_strstr_len (platform_choice, 3, "egl"))) {
display = GST_GL_DISPLAY (gst_gl_display_egl_new ());
}
#endif
if (!display) {
GST_INFO ("Could not create platform/winsys display. user specified %s "

View file

@ -50,6 +50,7 @@ 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
*/
typedef enum
@ -63,6 +64,7 @@ typedef enum
GST_GL_DISPLAY_TYPE_EGL = (1 << 5),
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_ANY = G_MAXUINT32
} GstGLDisplayType;

View file

@ -488,12 +488,14 @@ if need_platform_egl != 'no'
'egl/gstglcontext_egl.c',
'egl/gstgldisplay_egl.c',
'egl/gstglmemoryegl.c',
'egl/gstgldisplay_egl_device.c',
]
gl_egl_headers += [
'egl/gstegl.h',
'egl/gsteglimage.h',
'egl/gstgldisplay_egl.h',
'egl/gstglmemoryegl.h',
'egl/gstgldisplay_egl_device.h',
]
gl_platform_deps += egl_dep
glconf.set10('GST_GL_HAVE_PLATFORM_EGL', 1)