From b377112ee38912d316e77b4e2102041389dc0051 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Wed, 27 May 2015 10:58:10 +0100 Subject: [PATCH] gl: add GstGLContextGPUProcess backend It builds its GL vtable from a proc address provided by the application. --- configure.ac | 1 + ext/gl/gstglimagesink.c | 14 ++ gst-libs/gst/gl/Makefile.am | 5 +- gst-libs/gst/gl/gpuprocess/Makefile.am | 27 ++++ .../gl/gpuprocess/gstglcontext_gpu_process.c | 130 ++++++++++++++++++ .../gl/gpuprocess/gstglcontext_gpu_process.h | 70 ++++++++++ .../gl/gpuprocess/gstglwindow_gpu_process.c | 63 +++++++++ .../gl/gpuprocess/gstglwindow_gpu_process.h | 74 ++++++++++ gst-libs/gst/gl/gstglapi.c | 6 + gst-libs/gst/gl/gstglapi.h | 1 + 10 files changed, 390 insertions(+), 1 deletion(-) create mode 100644 gst-libs/gst/gl/gpuprocess/Makefile.am create mode 100644 gst-libs/gst/gl/gpuprocess/gstglcontext_gpu_process.c create mode 100644 gst-libs/gst/gl/gpuprocess/gstglcontext_gpu_process.h create mode 100644 gst-libs/gst/gl/gpuprocess/gstglwindow_gpu_process.c create mode 100644 gst-libs/gst/gl/gpuprocess/gstglwindow_gpu_process.h diff --git a/configure.ac b/configure.ac index 55eca0ee0d..43c197343b 100644 --- a/configure.ac +++ b/configure.ac @@ -3206,6 +3206,7 @@ gst-libs/gst/gl/dispmanx/Makefile gst-libs/gst/gl/glprototypes/Makefile gst-libs/gst/gl/eagl/Makefile gst-libs/gst/gl/egl/Makefile +gst-libs/gst/gl/gpuprocess/Makefile gst-libs/gst/gl/wayland/Makefile gst-libs/gst/gl/win32/Makefile gst-libs/gst/gl/x11/Makefile diff --git a/ext/gl/gstglimagesink.c b/ext/gl/gstglimagesink.c index 75d3b01ca4..648b8dac36 100644 --- a/ext/gl/gstglimagesink.c +++ b/ext/gl/gstglimagesink.c @@ -92,6 +92,7 @@ #include "gstglimagesink.h" #include "gstglsinkbin.h" +#include #if GST_GL_HAVE_PLATFORM_EGL #include @@ -675,6 +676,19 @@ _ensure_gl_setup (GstGLImageSink * gl_sink) GST_DEBUG_OBJECT (gl_sink, "Ensuring setup"); if (!gl_sink->context) { + if (GST_GL_IS_CONTEXT_GPU_PROCESS (gl_sink->other_context)) { + GstGLWindow *window = gst_gl_context_get_window (gl_sink->other_context); + gst_gl_window_set_draw_callback (window, + GST_GL_WINDOW_CB (gst_glimage_sink_on_draw), + gst_object_ref (gl_sink), (GDestroyNotify) gst_object_unref); + gst_object_unref (window); + + gl_sink->context = gl_sink->other_context; + gl_sink->other_context = NULL; + + return TRUE; + } + GST_OBJECT_LOCK (gl_sink->display); do { GstGLContext *other_context; diff --git a/gst-libs/gst/gl/Makefile.am b/gst-libs/gst/gl/Makefile.am index 8f5f115195..a27a32ed4c 100644 --- a/gst-libs/gst/gl/Makefile.am +++ b/gst-libs/gst/gl/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libgstgl-@GST_API_VERSION@.la SUBDIRS = glprototypes -DIST_SUBDIRS = glprototypes android x11 win32 cocoa wayland dispmanx egl eagl +DIST_SUBDIRS = glprototypes android x11 win32 cocoa wayland dispmanx egl eagl gpuprocess noinst_HEADERS = @@ -99,6 +99,9 @@ SUBDIRS += egl libgstgl_@GST_API_VERSION@_la_LIBADD += egl/libgstgl-egl.la endif +SUBDIRS += gpuprocess +libgstgl_@GST_API_VERSION@_la_LIBADD += gpuprocess/libgstgl-gpuprocess.la + configexecincludedir = $(libdir)/gstreamer-@GST_API_VERSION@/include/gst/gl nodist_configexecinclude_HEADERS = $(built_sys_header_configure) diff --git a/gst-libs/gst/gl/gpuprocess/Makefile.am b/gst-libs/gst/gl/gpuprocess/Makefile.am new file mode 100644 index 0000000000..4db0cf193c --- /dev/null +++ b/gst-libs/gst/gl/gpuprocess/Makefile.am @@ -0,0 +1,27 @@ +## Process this file with automake to produce Makefile.in + +noinst_LTLIBRARIES = libgstgl-gpuprocess.la + +libgstgl_gpuprocess_la_SOURCES = \ + gstglcontext_gpu_process.c \ + gstglwindow_gpu_process.c + +noinst_HEADERS = gstglwindow_gpu_process.h + +libgstgl_gpuprocessincludedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/gl/gpuprocess +libgstgl_gpuprocessinclude_HEADERS = \ + gstglcontext_gpu_process.h \ + gstglwindow_gpu_process.h + +libgstgl_gpuprocess_la_CFLAGS = \ + -I$(top_srcdir)/gst-libs \ + -I$(top_builddir)/gst-libs \ + $(GL_CFLAGS) \ + $(GST_PLUGINS_BASE_CFLAGS) \ + $(GST_BASE_CFLAGS) \ + $(GST_CFLAGS) + +libgstgl_gpuprocess_la_LDFLAGS = \ + $(GST_LIB_LDFLAGS) \ + $(GST_ALL_LDFLAGS) + diff --git a/gst-libs/gst/gl/gpuprocess/gstglcontext_gpu_process.c b/gst-libs/gst/gl/gpuprocess/gstglcontext_gpu_process.c new file mode 100644 index 0000000000..f4c6c158cd --- /dev/null +++ b/gst-libs/gst/gl/gpuprocess/gstglcontext_gpu_process.c @@ -0,0 +1,130 @@ +/* + * GStreamer + * Copyright (C) 2015 Julien Isorce + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstglcontext_gpu_process.h" +#include "gstglwindow_gpu_process.h" + +#define GST_GL_CONTEXT_GPU_PROCESS_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_CONTEXT_GPU_PROCESS, GstGLContextGPUProcessPrivate)) + +#define GST_CAT_DEFAULT gst_gl_context_debug + +G_DEFINE_TYPE (GstGLContextGPUProcess, gst_gl_context_gpu_process, + GST_GL_TYPE_CONTEXT); + +struct _GstGLContextGPUProcessPrivate +{ + GstGLAPI gl_api; +}; + +static guintptr +gst_gl_context_gpu_process_get_gl_context (GstGLContext * context) +{ + return 0; +} + +static GstGLAPI +gst_gl_context_gpu_process_get_gl_api (GstGLContext * context) +{ + return GST_GL_CONTEXT_GPU_PROCESS (context)->priv->gl_api; +} + +static GstGLPlatform +gst_gl_context_gpu_process_get_gl_platform (GstGLContext * context) +{ + return GST_GL_PLATFORM_GPU_PROCESS; +} + +static gboolean +gst_gl_context_gpu_process_activate (GstGLContext * context, gboolean activate) +{ + return TRUE; +} + +static void +gst_gl_context_gpu_process_class_init (GstGLContextGPUProcessClass * klass) +{ + GstGLContextClass *context_class = (GstGLContextClass *) klass; + + g_type_class_add_private (klass, sizeof (GstGLContextGPUProcessPrivate)); + + context_class->get_gl_context = + GST_DEBUG_FUNCPTR (gst_gl_context_gpu_process_get_gl_context); + context_class->get_gl_api = + GST_DEBUG_FUNCPTR (gst_gl_context_gpu_process_get_gl_api); + context_class->get_gl_platform = + GST_DEBUG_FUNCPTR (gst_gl_context_gpu_process_get_gl_platform); + context_class->activate = + GST_DEBUG_FUNCPTR (gst_gl_context_gpu_process_activate); +} + +static void +gst_gl_context_gpu_process_init (GstGLContextGPUProcess * context) +{ + context->priv = GST_GL_CONTEXT_GPU_PROCESS_GET_PRIVATE (context); +} + +GstGLContext * +gst_gl_context_gpu_process_new (GstGLDisplay * display, + GstGLAPI gl_api, GstGLProcAddrFunc proc_addr) +{ + GstGLContext *context = NULL; + GstGLContextGPUProcess *gpu_context = NULL; + GstGLContextClass *context_class = NULL; + GstGLWindow *window = NULL; + GError *error = NULL; + g_return_val_if_fail ((gst_gl_display_get_gl_api (display) & gl_api) != + GST_GL_API_NONE, NULL); + + gpu_context = g_object_new (GST_GL_TYPE_CONTEXT_GPU_PROCESS, NULL); + gpu_context->priv->gl_api = gl_api; + + context = GST_GL_CONTEXT (gpu_context); + + gst_gl_context_set_display (context, display); + gst_gl_display_add_context (display, context); + + context_class = GST_GL_CONTEXT_GET_CLASS (context); + + context_class->get_current_context = NULL; + context_class->get_proc_address = GST_DEBUG_FUNCPTR (proc_addr); + + gst_gl_context_activate (context, TRUE); + gst_gl_context_fill_info (context, &error); + + if (error) { + GST_ERROR_OBJECT (context, "Failed to create gpu process context: %s", + error->message); + g_error_free (error); + gst_object_unref (context); + return NULL; + } + + window = GST_GL_WINDOW (gst_gl_window_gpu_process_new (display)); + gst_gl_context_set_window (context, window); + GST_GL_WINDOW_GET_CLASS (window)->open (context->window, NULL); + gst_object_unref (window); + + return context; +} diff --git a/gst-libs/gst/gl/gpuprocess/gstglcontext_gpu_process.h b/gst-libs/gst/gl/gpuprocess/gstglcontext_gpu_process.h new file mode 100644 index 0000000000..d99e9e56df --- /dev/null +++ b/gst-libs/gst/gl/gpuprocess/gstglcontext_gpu_process.h @@ -0,0 +1,70 @@ +/* + * GStreamer + * Copyright (C) 2015 Julien Isorce + * + * 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_CONTEXT_GPU_PROCESS_H__ +#define __GST_GL_CONTEXT_GPU_PROCESS_H__ + +#include + +G_BEGIN_DECLS + +#define GST_GL_TYPE_CONTEXT_GPU_PROCESS (gst_gl_context_gpu_process_get_type()) +#define GST_GL_CONTEXT_GPU_PROCESS(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_GL_TYPE_CONTEXT_GPU_PROCESS, GstGLContextGPUProcess)) +#define GST_GL_CONTEXT_GPU_PROCESS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GST_GL_TYPE_CONTEXT_GPU_PROCESS, GstGLContextGPUProcessClass)) +#define GST_GL_IS_CONTEXT_GPU_PROCESS(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_GL_TYPE_CONTEXT_GPU_PROCESS)) +#define GST_GL_IS_CONTEXT_GPU_PROCESS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_GL_TYPE_CONTEXT_GPU_PROCESS)) +#define GST_GL_CONTEXT_GPU_PROCESS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_GL_TYPE_CONTEXT_GPU_PROCESS, GstGLContextGPUProcessClass)) + +typedef struct _GstGLContextGPUProcess GstGLContextGPUProcess; +typedef struct _GstGLContextGPUProcessPrivate GstGLContextGPUProcessPrivate; +typedef struct _GstGLContextGPUProcessClass GstGLContextGPUProcessClass; + +typedef gpointer (* GstGLProcAddrFunc) (GstGLContext *context, const gchar *name); + +/** + * GstGLContextGPUProcess: + * + * Opaque #GstGLContextGPUProcess object + */ +struct _GstGLContextGPUProcess { + GstGLContext parent; + + /*< private >*/ + GstGLContextGPUProcessPrivate *priv; + + /*< private >*/ + gpointer _reserved[GST_PADDING]; +}; + +struct _GstGLContextGPUProcessClass { + GstGLContextClass parent; + + /*< private >*/ + gpointer _reserved[GST_PADDING]; +}; + +GType gst_gl_context_gpu_process_get_type (void); + +GstGLContext * gst_gl_context_gpu_process_new (GstGLDisplay * display, + GstGLAPI gl_api, GstGLProcAddrFunc proc_addr); + +G_END_DECLS + +#endif /* __GST_GL_CONTEXT_GPU_PROCESS_H__ */ diff --git a/gst-libs/gst/gl/gpuprocess/gstglwindow_gpu_process.c b/gst-libs/gst/gl/gpuprocess/gstglwindow_gpu_process.c new file mode 100644 index 0000000000..ffdbde996f --- /dev/null +++ b/gst-libs/gst/gl/gpuprocess/gstglwindow_gpu_process.c @@ -0,0 +1,63 @@ +/* + * GStreamer + * Copyright (C) 2015 Julien Isorce + * + * 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. + */ + +#define GLIB_DISABLE_DEPRECATION_WARNINGS + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstglwindow_gpu_process.h" + +#define GST_GL_WINDOW_GPU_PROCESS_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_WINDOW_GPU_PROCESS, GstGLWindowGPUProcessPrivate)) + +#define GST_CAT_DEFAULT gst_gl_window_debug + +#define gst_gl_window_gpu_process_parent_class parent_class +G_DEFINE_TYPE (GstGLWindowGPUProcess, gst_gl_window_gpu_process, + GST_GL_TYPE_WINDOW); + +struct _GstGLWindowGPUProcessPrivate +{ +}; + +static void +gst_gl_window_gpu_process_class_init (GstGLWindowGPUProcessClass * klass) +{ + g_type_class_add_private (klass, sizeof (GstGLWindowGPUProcessPrivate)); +} + +static void +gst_gl_window_gpu_process_init (GstGLWindowGPUProcess * window) +{ + window->priv = GST_GL_WINDOW_GPU_PROCESS_GET_PRIVATE (window); +} + +GstGLWindowGPUProcess * +gst_gl_window_gpu_process_new (GstGLDisplay * display) +{ + GstGLWindowGPUProcess *window = + g_object_new (GST_GL_TYPE_WINDOW_GPU_PROCESS, NULL); + + GST_GL_WINDOW (window)->display = gst_object_ref (display); + + return window; +} diff --git a/gst-libs/gst/gl/gpuprocess/gstglwindow_gpu_process.h b/gst-libs/gst/gl/gpuprocess/gstglwindow_gpu_process.h new file mode 100644 index 0000000000..c7b6b66b31 --- /dev/null +++ b/gst-libs/gst/gl/gpuprocess/gstglwindow_gpu_process.h @@ -0,0 +1,74 @@ +/* + * GStreamer + * Copyright (C) 2015 Julien Isorce + * + * 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_WINDOW_GPU_PROCESS_H__ +#define __GST_GL_WINDOW_GPU_PROCESS_H__ + +#include +#include + +G_BEGIN_DECLS + +#define GST_GL_TYPE_WINDOW_GPU_PROCESS (gst_gl_window_gpu_process_get_type()) +#define GST_GL_WINDOW_GPU_PROCESS(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_GL_TYPE_WINDOW_GPU_PROCESS, GstGLWindowGPUProcess)) +#define GST_GL_WINDOW_GPU_PROCESS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GST_GL_TYPE_WINDOW_GPU_PROCESS, GstGLWindowGPUProcessClass)) +#define GST_GL_IS_WINDOW_GPU_PROCESS(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_GL_TYPE_WINDOW_GPU_PROCESS)) +#define GST_GL_IS_WINDOW_GPU_PROCESS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_GL_TYPE_WINDOW_GPU_PROCESS)) +#define GST_GL_WINDOW_GPU_PROCESS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_GL_TYPE_WINDOW_GPU_PROCESS, GstGLWindowGPUProcessClass)) + +typedef struct _GstGLWindowGPUProcess GstGLWindowGPUProcess; +typedef struct _GstGLWindowGPUProcessPrivate GstGLWindowGPUProcessPrivate; +typedef struct _GstGLWindowGPUProcessClass GstGLWindowGPUProcessClass; + +/** + * GstGLWindowGPUProcess: + * + * Opaque #GstGLWindowGPUProcess object + */ +struct _GstGLWindowGPUProcess +{ + GstGLWindow parent; + + /*< private >*/ + GstGLWindowGPUProcessPrivate *priv; + + /*< private >*/ + gpointer _reserved[GST_PADDING]; +}; + +/** + * GstGLWindowGPUProcessClass: + * + * Opaque #GstGLWindowGPUProcessClass object + */ +struct _GstGLWindowGPUProcessClass { + GstGLWindowClass parent_class; + + /*< private >*/ + gpointer _reserved[GST_PADDING]; +}; + +GType gst_gl_window_gpu_process_get_type (void); + +GstGLWindowGPUProcess * gst_gl_window_gpu_process_new (GstGLDisplay * display); + +G_END_DECLS + +#endif /* __GST_GL_WINDOW_GPU_PROCESS_H__ */ diff --git a/gst-libs/gst/gl/gstglapi.c b/gst-libs/gst/gl/gstglapi.c index 3bee14b01e..f824aa1947 100644 --- a/gst-libs/gst/gl/gstglapi.c +++ b/gst-libs/gst/gl/gstglapi.c @@ -152,6 +152,9 @@ gst_gl_platform_to_string (GstGLPlatform platform) if (platform & GST_GL_PLATFORM_CGL) { str = g_string_append (str, "cgl "); } + if (platform & GST_GL_PLATFORM_GPU_PROCESS) { + str = g_string_append (str, "gpu_process "); + } out: if (!str) @@ -193,6 +196,9 @@ gst_gl_platform_from_string (const gchar * platform_s) } else if (g_strstr_len (platform, 3, "cgl")) { ret |= GST_GL_PLATFORM_CGL; platform = &platform[3]; + } else if (g_strstr_len (platform, 11, "gpu_process")) { + ret |= GST_GL_PLATFORM_GPU_PROCESS; + platform = &platform[11]; } else { GST_ERROR ("Error parsing \'%s\'", platform); break; diff --git a/gst-libs/gst/gl/gstglapi.h b/gst-libs/gst/gl/gstglapi.h index c260590479..a7ba464957 100644 --- a/gst-libs/gst/gl/gstglapi.h +++ b/gst-libs/gst/gl/gstglapi.h @@ -116,6 +116,7 @@ typedef enum GST_GL_PLATFORM_WGL = (1 << 2), GST_GL_PLATFORM_CGL = (1 << 3), GST_GL_PLATFORM_EAGL = (1 << 4), + GST_GL_PLATFORM_GPU_PROCESS = (1 << 5), GST_GL_PLATFORM_ANY = G_MAXUINT32 } GstGLPlatform;